qt5base-lts/tests/auto/qtipc/qsystemsemaphore/tst_qsystemsemaphore.cpp
Jyri Tahtela f9f395c28b Update licenseheader text in source files for qtbase Qt module
Updated version of LGPL and FDL licenseheaders.
Apply release phase licenseheaders for all source files.

Reviewed-by: Trust Me
2011-05-24 12:34:08 +03:00

320 lines
9.8 KiB
C++

/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <qsystemsemaphore.h>
//TESTED_CLASS=
//TESTED_FILES=
#define EXISTING_SHARE "existing"
#ifdef Q_OS_WINCE
#define LACKEYLOC "."
#else
#define LACKEYLOC "../lackey"
#endif
#define LACKYWAITTIME 10000
class tst_QSystemSemaphore : public QObject
{
Q_OBJECT
public:
tst_QSystemSemaphore();
virtual ~tst_QSystemSemaphore();
public Q_SLOTS:
void init();
void cleanup();
private slots:
void key_data();
void key();
void basicacquire();
void complexacquire();
void basicProcesses();
void processes_data();
void processes();
void undo();
void initialValue();
private:
QSystemSemaphore *existingLock;
QString makeFile(const QString &resource)
{
QFile memory(resource);
if (!memory.open(QIODevice::ReadOnly)) {
qDebug() << "error reading resource" << resource;
return QString();
}
QTemporaryFile *file = new QTemporaryFile;
file->open();
file->write(memory.readAll());
tempFiles.append(file);
file->flush();
#ifdef Q_OS_WINCE
// flush does not flush to disk on Windows CE. It flushes it into its application
// cache. Thus we need to close the file to be able that other processes(lackey) can read it
QString fileName = file->fileName();
file->close();
return fileName;
#endif
return file->fileName();
}
QString acquire_js() { return makeFile(":/systemsemaphore_acquire.js"); }
QString release_js() { return makeFile(":/systemsemaphore_release.js"); }
QString acquirerelease_js() { return makeFile(":/systemsemaphore_acquirerelease.js"); }
QList<QTemporaryFile*> tempFiles;
};
tst_QSystemSemaphore::tst_QSystemSemaphore()
{
if (!QFile::exists(LACKEYLOC "/lackey"))
qWarning() << "lackey executable doesn't exists!";
}
tst_QSystemSemaphore::~tst_QSystemSemaphore()
{
qDeleteAll(tempFiles);
}
void tst_QSystemSemaphore::init()
{
existingLock = new QSystemSemaphore(EXISTING_SHARE, 1, QSystemSemaphore::Create);
}
void tst_QSystemSemaphore::cleanup()
{
delete existingLock;
}
void tst_QSystemSemaphore::key_data()
{
QTest::addColumn<QString>("constructorKey");
QTest::addColumn<QString>("setKey");
QTest::newRow("null, null") << QString() << QString();
QTest::newRow("null, one") << QString() << QString("one");
QTest::newRow("one, two") << QString("one") << QString("two");
}
/*!
Basic key testing
*/
void tst_QSystemSemaphore::key()
{
QFETCH(QString, constructorKey);
QFETCH(QString, setKey);
QSystemSemaphore sem(constructorKey);
QCOMPARE(sem.key(), constructorKey);
QCOMPARE(sem.error(), QSystemSemaphore::NoError);
QCOMPARE(sem.errorString(), QString());
sem.setKey(setKey);
QCOMPARE(sem.key(), setKey);
QCOMPARE(sem.error(), QSystemSemaphore::NoError);
QCOMPARE(sem.errorString(), QString());
}
void tst_QSystemSemaphore::basicacquire()
{
QSystemSemaphore sem("QSystemSemaphore_basicacquire", 1, QSystemSemaphore::Create);
QVERIFY(sem.acquire());
QCOMPARE(sem.error(), QSystemSemaphore::NoError);
QVERIFY(sem.release());
QCOMPARE(sem.error(), QSystemSemaphore::NoError);
QCOMPARE(sem.errorString(), QString());
}
void tst_QSystemSemaphore::complexacquire()
{
QSystemSemaphore sem("QSystemSemaphore_complexacquire", 2, QSystemSemaphore::Create);
QVERIFY(sem.acquire());
QVERIFY(sem.release());
QVERIFY(sem.acquire());
QVERIFY(sem.release());
QVERIFY(sem.acquire());
QVERIFY(sem.acquire());
QVERIFY(sem.release());
QVERIFY(sem.release());
QCOMPARE(sem.error(), QSystemSemaphore::NoError);
QCOMPARE(sem.errorString(), QString());
}
void tst_QSystemSemaphore::basicProcesses()
{
#if defined (Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86)
QSKIP("Cannot launch multiple Qt processes in Symbian emulator", SkipAll);
#endif
QSystemSemaphore sem("store", 0, QSystemSemaphore::Create);
QStringList acquireArguments = QStringList() << acquire_js();
QStringList releaseArguments = QStringList() << release_js();
QProcess acquire;
acquire.setProcessChannelMode(QProcess::ForwardedChannels);
QProcess release;
release.setProcessChannelMode(QProcess::ForwardedChannels);
acquire.start(LACKEYLOC "/lackey", acquireArguments);
acquire.waitForFinished(LACKYWAITTIME);
QVERIFY(acquire.state() == QProcess::Running);
acquire.kill();
release.start(LACKEYLOC "/lackey", releaseArguments);
acquire.waitForFinished(LACKYWAITTIME);
release.waitForFinished(LACKYWAITTIME);
QVERIFY(acquire.state() == QProcess::NotRunning);
}
void tst_QSystemSemaphore::processes_data()
{
QTest::addColumn<int>("processes");
for (int i = 0; i < 5; ++i) {
QTest::newRow("1 process") << 1;
QTest::newRow("3 process") << 3;
QTest::newRow("10 process") << 10;
}
}
void tst_QSystemSemaphore::processes()
{
#if defined (Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86)
QSKIP("Cannot launch multiple Qt processes in Symbian emulator", SkipAll);
#endif
QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
QFETCH(int, processes);
QStringList scripts;
for (int i = 0; i < processes; ++i)
scripts.append(acquirerelease_js());
QList<QProcess*> consumers;
for (int i = 0; i < scripts.count(); ++i) {
QStringList arguments = QStringList() << scripts.at(i);
QProcess *p = new QProcess;
p->setProcessChannelMode(QProcess::ForwardedChannels);
consumers.append(p);
#ifdef Q_OS_WINCE
// We can't start the same executable twice on Windows CE.
// Create a copy instead.
QString lackeyCopy = QLatin1String(LACKEYLOC "/lackey");
if (i > 0) {
lackeyCopy.append(QString::number(i));
lackeyCopy.append(QLatin1String(".exe"));
if (!QFile::exists(lackeyCopy))
QVERIFY(QFile::copy(LACKEYLOC "/lackey.exe", lackeyCopy));
}
p->start(lackeyCopy, arguments);
#else
p->start(LACKEYLOC "/lackey", arguments);
#endif
}
while (!consumers.isEmpty()) {
consumers.first()->waitForFinished();
QCOMPARE(consumers.first()->exitStatus(), QProcess::NormalExit);
QCOMPARE(consumers.first()->exitCode(), 0);
delete consumers.takeFirst();
}
}
void tst_QSystemSemaphore::undo()
{
#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
QSKIP("This test only checks a unix behavior", SkipSingle);
#endif
QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
QStringList acquireArguments = QStringList() << acquire_js();
QProcess acquire;
acquire.setProcessChannelMode(QProcess::ForwardedChannels);
acquire.start(LACKEYLOC "/lackey", acquireArguments);
acquire.waitForFinished(LACKYWAITTIME);
QVERIFY(acquire.state()== QProcess::NotRunning);
// At process exit the kernel should auto undo
acquire.start(LACKEYLOC "/lackey", acquireArguments);
acquire.waitForFinished(LACKYWAITTIME);
QVERIFY(acquire.state()== QProcess::NotRunning);
}
void tst_QSystemSemaphore::initialValue()
{
#if defined (Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86)
QSKIP("Cannot launch multiple Qt processes in Symbian emulator", SkipAll);
#endif
QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
QStringList acquireArguments = QStringList() << acquire_js();
QStringList releaseArguments = QStringList() << release_js();
QProcess acquire;
acquire.setProcessChannelMode(QProcess::ForwardedChannels);
QProcess release;
release.setProcessChannelMode(QProcess::ForwardedChannels);
acquire.start(LACKEYLOC "/lackey", acquireArguments);
acquire.waitForFinished(LACKYWAITTIME);
QVERIFY(acquire.state()== QProcess::NotRunning);
acquire.start(LACKEYLOC "/lackey", acquireArguments << "2");
acquire.waitForFinished(LACKYWAITTIME);
QVERIFY(acquire.state()== QProcess::Running);
acquire.kill();
release.start(LACKEYLOC "/lackey", releaseArguments);
acquire.waitForFinished(LACKYWAITTIME);
release.waitForFinished(LACKYWAITTIME);
QVERIFY(acquire.state()== QProcess::NotRunning);
}
QTEST_MAIN(tst_QSystemSemaphore)
#include "tst_qsystemsemaphore.moc"