1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the QtSystems module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL21$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 or version 3 as published by the Free
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22** following information to ensure the GNU Lesser General Public License
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25**
26** As a special exception, The Qt Company gives you certain additional
27** rights. These rights are described in The Qt Company LGPL Exception
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29**
30** $QT_END_LICENSE$
31**
32****************************************************************************/
33
34//TESTED_COMPONENT=src/serviceframework
35
36#include <QCoreApplication>
37#include "qservicemanager.h"
38#include "qservicefilter.h"
39#include "service.h"
40#include <QTimer>
41#include <QMetaObject>
42#include <QMetaMethod>
43#include <QtTest/QtTest>
44#include <qservice.h>
45#include <qremoteserviceregister.h>
46#include <QDebug>
47#include <QByteArray>
48#include <QDataStream>
49
50QT_USE_NAMESPACE
51Q_DECLARE_METATYPE(QServiceFilter);
52Q_DECLARE_METATYPE(QVariant);
53Q_DECLARE_METATYPE(QList<QString>);
54
55
56class tst_QRemoteServiceRegister: public QObject
57{
58 Q_OBJECT
59public:
60
61private slots:
62 void initTestCase();
63 void cleanupTestCase();
64 void checkCreateEntryWithEmptyServiceName();
65 void checkOperators();
66 void checkPublish();
67 void tst_instanceClosed();
68
69private:
70 QRemoteServiceRegister* serviceRegister;
71 QRemoteServiceRegister::Entry uniqueEntry;
72 QRemoteServiceRegister::Entry uniqueEntry2;
73
74 QObject *connectToService(const QString &serviceName);
75 bool servicePublished;
76};
77
78void mySecurityFilterFunction(QServiceClientCredentials *cred)
79{
80 // allow the superuser
81 if (cred->getUserIdentifier() == 0) {
82 cred->setClientAccepted(false);
83 }
84
85 cred->setClientAccepted(true);
86}
87
88void alwaysPass(QServiceClientCredentials *cred)
89{
90 cred->setClientAccepted(true);
91}
92
93void tst_QRemoteServiceRegister::initTestCase()
94{
95 qRegisterMetaType<QServiceFilter>(typeName: "QServiceFilter");
96 qRegisterMetaTypeStreamOperators<QServiceFilter>(typeName: "QServiceFilter");
97 qRegisterMetaType<QList<QString> >(typeName: "QList<QString>");
98 qRegisterMetaTypeStreamOperators<QList<QString> >(typeName: "QList<QString>");
99
100 serviceRegister = new QRemoteServiceRegister();
101
102 //Check setting of close on last instance
103// serviceRegister->setQuitOnLastInstanceClosed(false);
104// QVERIFY(serviceRegister->quitOnLastInstanceClosed() == false);
105 serviceRegister->setQuitOnLastInstanceClosed(true);
106 QVERIFY(serviceRegister->quitOnLastInstanceClosed() == true);
107
108 //check setting a security filter
109 serviceRegister->setSecurityFilter(mySecurityFilterFunction);
110
111 QServiceManager* manager = new QServiceManager(this);
112 const QString path = QFINDTESTDATA("/xmldata/rsrexampleservice.xml");
113 bool r = manager->addService(xmlFilePath: path);
114 QVERIFY2(r, qPrintable(QString("Cannot register RSRExampleService - %1").arg(path)));
115
116 // D-Bus auto registration
117#ifndef QT_NO_DBUS
118 const QString &file = QDir::homePath() + "/.local/share/dbus-1/services/" +
119 "com.nokia.qt.rsrunittest.service";
120 QFile data(file);
121 if (data.open(flags: QFile::WriteOnly)) {
122 QTextStream out(&data);
123 out << "[D-BUS Service]\n"
124 << "Name=com.nokia.qtmobility.sfw.RSRExampleService" << '\n'
125 << "Exec=" << QFileInfo("./qt_sfw_example_rsr_unittest").absoluteFilePath();
126 data.close();
127 }
128#endif
129
130 //register the unique service
131 uniqueEntry = serviceRegister->createEntry<QRemoteServiceRegisterService>(
132 serviceName: "RSRExampleService", interfaceName: "com.nokia.qt.rsrunittest", version: "1.0");
133
134 bool valid = uniqueEntry.isValid();
135 QVERIFY(valid == true);
136
137 uniqueEntry2 = serviceRegister->createEntry<QRemoteServiceRegisterService>(
138 serviceName: "RSRExampleService", interfaceName: "com.nokia.qt.rsrunittest", version: "1.0");
139
140 valid = uniqueEntry2.isValid();
141 QVERIFY(valid == true);
142
143 servicePublished = false;
144}
145
146void tst_QRemoteServiceRegister::cleanupTestCase()
147{
148#ifndef QT_NO_DBUS
149 const QString &file = QDir::homePath() + "/.local/share/dbus-1/services/" +
150 "com.nokia.qt.rsrunittest.service";
151 QFile::remove(fileName: file);
152#endif
153
154 // clean up the unit, don't leave it registered
155 QServiceManager m;
156 m.removeService(serviceName: "RSRExampleService");
157 delete serviceRegister;
158}
159
160void tst_QRemoteServiceRegister::checkCreateEntryWithEmptyServiceName()
161{
162 QRemoteServiceRegister::Entry emptyservicename =
163 serviceRegister->createEntry<QRemoteServiceRegisterService>(
164 serviceName: "", interfaceName: "", version: "");
165 QVERIFY(emptyservicename.serviceName() == "");
166 bool valid = emptyservicename.isValid();
167 QVERIFY(valid == false);
168}
169
170void tst_QRemoteServiceRegister::checkOperators()
171{
172 //== operator
173 bool equal = (uniqueEntry == uniqueEntry2 ? true : false);
174 QVERIFY(equal == true);
175
176 //!= operator
177 bool notequal = (uniqueEntry != uniqueEntry2 ? true : false);
178 QVERIFY(notequal == false);
179
180 //= operator
181 QRemoteServiceRegister::Entry assignval;
182 assignval = uniqueEntry;
183 equal = (assignval == uniqueEntry ? true : false);
184 QVERIFY(equal == true);
185
186 //QDataStream << >>
187#ifndef QT_NO_DATASTREAM
188 QByteArray barray = QByteArray();
189 QDataStream streamOut(&barray, QIODevice::WriteOnly);
190 streamOut.setVersion(QDataStream::Qt_4_6);
191 streamOut << uniqueEntry;
192 QDataStream streamIn(&barray, QIODevice::ReadOnly);
193 streamOut.setVersion(QDataStream::Qt_4_6);
194 QRemoteServiceRegister::Entry streamedentry;
195 streamIn >> streamedentry;
196 QVERIFY(uniqueEntry.serviceName() == streamedentry.serviceName());
197 QVERIFY(uniqueEntry.interfaceName() == streamedentry.interfaceName());
198 QVERIFY(uniqueEntry.version() == streamedentry.version());
199#endif
200}
201
202void tst_QRemoteServiceRegister::checkPublish()
203{
204 //publish the registered services
205 serviceRegister->publishEntries(ident: "qt_sfw_example_rsr_unittest");
206 servicePublished = true;
207
208 //check instantiation type
209 //- default value
210 QRemoteServiceRegister::InstanceType type = uniqueEntry.instantiationType();
211 QRemoteServiceRegister::InstanceType type2 = uniqueEntry2.instantiationType();
212 QVERIFY(type == QRemoteServiceRegister::PrivateInstance);
213 QVERIFY(type2 == QRemoteServiceRegister::PrivateInstance);
214 //check setting the type
215 uniqueEntry2.setInstantiationType(QRemoteServiceRegister::GlobalInstance);
216 type2 = uniqueEntry2.instantiationType();
217 QVERIFY(type2 == QRemoteServiceRegister::GlobalInstance);
218}
219
220Q_DECLARE_METATYPE(QRemoteServiceRegister::Entry);
221
222void tst_QRemoteServiceRegister::tst_instanceClosed()
223{
224 qRegisterMetaType<QRemoteServiceRegister::Entry>(typeName: "QRemoteServiceRegister::Entry");
225 if(!servicePublished)
226 serviceRegister->publishEntries(ident: "qt_sfw_example_rsr_unittest");
227
228 serviceRegister->setSecurityFilter(alwaysPass);
229 QSignalSpy spy(serviceRegister,SIGNAL(instanceClosed(QRemoteServiceRegister::Entry)));
230 QSignalSpy spyAll(serviceRegister,SIGNAL(allInstancesClosed()));
231
232 QObject *o = connectToService(serviceName: "RSRExampleService");
233 QVERIFY(o);
234
235 delete o;
236
237 QTRY_COMPARE(spy.count(), 1);
238 QCOMPARE(spyAll.count(), 1);
239
240}
241
242QObject *tst_QRemoteServiceRegister::connectToService(const QString &serviceName)
243{
244 QServiceManager manager;
245
246 QList<QServiceInterfaceDescriptor> list = manager.findInterfaces(serviceName);
247 if (list.isEmpty()) {
248 qWarning() << "Couldn't find service" << serviceName << manager.findServices(interfaceName: "qt_sfw_example_rsr_unittest");
249 return 0;
250 }
251
252 // Get the interface descriptor
253 QServiceInterfaceDescriptor desc = list.at(i: 0);
254 if (!desc.isValid()) {
255 qWarning() << "Warning: Invalid service interface descriptor for" << serviceName;
256 return 0;
257 }
258
259 QObject* service = manager.loadInterface(descriptor: desc);
260 if (!service) {
261 qWarning() << "Couldn't load service interface for" << serviceName;
262 return 0;
263 }
264 return service;
265}
266
267
268QTEST_MAIN(tst_QRemoteServiceRegister);
269#include "tst_qremoteserviceregister.moc"
270

source code of qtsystems/tests/auto/serviceframework/qremoteserviceregister/tst_qremoteserviceregister.cpp