1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the test suite of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
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 Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
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 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
42
#include <QtTest/QtTest>
43
#include <QtCore/QSystemSemaphore>
44
#include <QtCore/QVector>
45
#include <QtCore/QTemporaryDir>
47
#define EXISTING_SHARE "existing"
48
#define HELPERWAITTIME 10000
50
class tst_QSystemSemaphore : public QObject
55
tst_QSystemSemaphore();
67
void complexacquire();
69
void basicProcesses();
71
void processes_data();
80
QString helperBinary();
81
QSystemSemaphore *existingLock;
84
tst_QSystemSemaphore::tst_QSystemSemaphore()
88
void tst_QSystemSemaphore::initTestCase()
90
QVERIFY2(!helperBinary().isEmpty(), "Could not find helper binary");
93
void tst_QSystemSemaphore::init()
95
existingLock = new QSystemSemaphore(EXISTING_SHARE, 1, QSystemSemaphore::Create);
98
void tst_QSystemSemaphore::cleanup()
103
void tst_QSystemSemaphore::key_data()
105
QTest::addColumn<QString>("constructorKey");
106
QTest::addColumn<QString>("setKey");
108
QTest::newRow("null, null") << QString() << QString();
109
QTest::newRow("null, one") << QString() << QString("one");
110
QTest::newRow("one, two") << QString("one") << QString("two");
116
void tst_QSystemSemaphore::key()
118
QFETCH(QString, constructorKey);
119
QFETCH(QString, setKey);
121
QSystemSemaphore sem(constructorKey);
122
QCOMPARE(sem.key(), constructorKey);
123
QCOMPARE(sem.error(), QSystemSemaphore::NoError);
124
QCOMPARE(sem.errorString(), QString());
127
QCOMPARE(sem.key(), setKey);
128
QCOMPARE(sem.error(), QSystemSemaphore::NoError);
129
QCOMPARE(sem.errorString(), QString());
132
void tst_QSystemSemaphore::basicacquire()
134
QSystemSemaphore sem("QSystemSemaphore_basicacquire", 1, QSystemSemaphore::Create);
135
QVERIFY(sem.acquire());
136
QCOMPARE(sem.error(), QSystemSemaphore::NoError);
137
QVERIFY(sem.release());
138
QCOMPARE(sem.error(), QSystemSemaphore::NoError);
139
QCOMPARE(sem.errorString(), QString());
142
void tst_QSystemSemaphore::complexacquire()
144
QSystemSemaphore sem("QSystemSemaphore_complexacquire", 2, QSystemSemaphore::Create);
145
QVERIFY(sem.acquire());
146
QVERIFY(sem.release());
147
QVERIFY(sem.acquire());
148
QVERIFY(sem.release());
149
QVERIFY(sem.acquire());
150
QVERIFY(sem.acquire());
151
QVERIFY(sem.release());
152
QVERIFY(sem.release());
153
QCOMPARE(sem.error(), QSystemSemaphore::NoError);
154
QCOMPARE(sem.errorString(), QString());
157
void tst_QSystemSemaphore::basicProcesses()
159
QSystemSemaphore sem("store", 0, QSystemSemaphore::Create);
162
acquire.setProcessChannelMode(QProcess::ForwardedChannels);
165
release.setProcessChannelMode(QProcess::ForwardedChannels);
167
acquire.start(helperBinary(), QStringList("acquire"));
168
QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
169
acquire.waitForFinished(HELPERWAITTIME);
170
QVERIFY(acquire.state() == QProcess::Running);
172
release.start(helperBinary(), QStringList("release"));
173
QVERIFY2(release.waitForStarted(), "Could not start helper binary");
174
acquire.waitForFinished(HELPERWAITTIME);
175
release.waitForFinished(HELPERWAITTIME);
176
QVERIFY(acquire.state() == QProcess::NotRunning);
179
void tst_QSystemSemaphore::processes_data()
181
QTest::addColumn<int>("processes");
182
for (int i = 0; i < 5; ++i) {
183
QTest::newRow("1 process") << 1;
184
QTest::newRow("3 process") << 3;
185
QTest::newRow("10 process") << 10;
189
void tst_QSystemSemaphore::processes()
191
QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
193
QFETCH(int, processes);
194
QVector<QString> scripts(processes, "acquirerelease");
196
QList<QProcess*> consumers;
197
for (int i = 0; i < scripts.count(); ++i) {
198
QProcess *p = new QProcess;
199
p->setProcessChannelMode(QProcess::ForwardedChannels);
201
p->start(helperBinary(), QStringList(scripts.at(i)));
204
while (!consumers.isEmpty()) {
205
consumers.first()->waitForFinished();
206
QCOMPARE(consumers.first()->exitStatus(), QProcess::NormalExit);
207
QCOMPARE(consumers.first()->exitCode(), 0);
208
delete consumers.takeFirst();
212
// This test only checks a unix behavior.
214
void tst_QSystemSemaphore::undo()
216
QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
218
QStringList acquireArguments = QStringList("acquire");
220
acquire.setProcessChannelMode(QProcess::ForwardedChannels);
221
acquire.start(helperBinary(), acquireArguments);
222
QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
223
acquire.waitForFinished(HELPERWAITTIME);
224
QVERIFY(acquire.state()== QProcess::NotRunning);
226
// At process exit the kernel should auto undo
228
acquire.start(helperBinary(), acquireArguments);
229
QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
230
acquire.waitForFinished(HELPERWAITTIME);
231
QVERIFY(acquire.state()== QProcess::NotRunning);
235
void tst_QSystemSemaphore::initialValue()
237
QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
239
QStringList acquireArguments = QStringList("acquire");
240
QStringList releaseArguments = QStringList("release");
242
acquire.setProcessChannelMode(QProcess::ForwardedChannels);
245
release.setProcessChannelMode(QProcess::ForwardedChannels);
247
acquire.start(helperBinary(), acquireArguments);
248
QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
249
acquire.waitForFinished(HELPERWAITTIME);
250
QVERIFY(acquire.state()== QProcess::NotRunning);
252
acquire.start(helperBinary(), acquireArguments << QLatin1String("2"));
253
QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
254
acquire.waitForFinished(HELPERWAITTIME);
255
QVERIFY(acquire.state()== QProcess::Running);
258
release.start(helperBinary(), releaseArguments);
259
QVERIFY2(release.waitForStarted(), "Could not start helper binary");
260
acquire.waitForFinished(HELPERWAITTIME);
261
release.waitForFinished(HELPERWAITTIME);
262
QVERIFY(acquire.state()== QProcess::NotRunning);
265
QString tst_QSystemSemaphore::helperBinary()
267
QString binary = QStringLiteral("helperbinary");
269
binary += QStringLiteral(".exe");
271
return QFINDTESTDATA(binary);
273
QTEST_MAIN(tst_QSystemSemaphore)
274
#include "tst_qsystemsemaphore.moc"