Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F16569867
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
25 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/kdecore/tests/kservicetest.cpp b/kdecore/tests/kservicetest.cpp
index 747e11ad67..24fbbae674 100644
--- a/kdecore/tests/kservicetest.cpp
+++ b/kdecore/tests/kservicetest.cpp
@@ -1,583 +1,583 @@
/*
* Copyright (C) 2006 David Faure <faure@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <locale.h>
#include "kservicetest.h"
#include "kservicetest.moc"
#include <qtest_kde.h>
#include <kconfig.h>
#include <kconfiggroup.h>
#include <kdesktopfile.h>
#include <ksycoca.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <kprotocolinfo.h>
#include <kdebug.h>
#include <kprocess.h>
#include <kservicegroup.h>
#include <kservicetypetrader.h>
#include <kservicetype.h>
#include <kservicetypeprofile.h>
#include <QtCore/Q_PID>
QTEST_KDEMAIN_CORE( KServiceTest )
static void eraseProfiles()
{
QString profilerc = KStandardDirs::locateLocal( "config", "profilerc" );
if ( !profilerc.isEmpty() )
QFile::remove( profilerc );
profilerc = KStandardDirs::locateLocal( "config", "servicetype_profilerc" );
if ( !profilerc.isEmpty() )
QFile::remove( profilerc );
}
void KServiceTest::initTestCase()
{
// A non-C locale is necessary for some tests.
// This locale must have the following properties:
// - some character other than dot as decimal separator
// If it cannot be set, locale-dependent tests are skipped.
setlocale(LC_ALL, "fr_FR.utf8");
m_hasNonCLocale = (setlocale(LC_ALL, NULL) == QByteArray("fr_FR.utf8"));
if (!m_hasNonCLocale) {
kDebug() << "Setting locale to fr_FR.utf8 failed";
}
m_hasKde4Konsole = false;
eraseProfiles();
// Create some fake services for the tests below, and ensure they are in ksycoca.
// fakeservice: deleted and recreated by testKSycocaUpdate, don't use in other tests
bool mustUpdateKSycoca = !KService::serviceByDesktopPath("fakeservice.desktop");
const QString fakeService = KStandardDirs::locateLocal("services", "fakeservice.desktop");
if (!QFile::exists(fakeService)) {
mustUpdateKSycoca = true;
createFakeService();
}
// fakepart: a readwrite part, like katepart
if (!KService::serviceByDesktopPath("fakepart.desktop")) {
mustUpdateKSycoca = true;
}
const QString fakePart = KStandardDirs::locateLocal("services", "fakepart.desktop");
if (!QFile::exists(fakePart)) {
mustUpdateKSycoca = true;
KDesktopFile file(fakePart);
KConfigGroup group = file.desktopGroup();
group.writeEntry("Name", "FakePart");
group.writeEntry("Type", "Service");
group.writeEntry("X-KDE-Library", "fakepart");
group.writeEntry("X-KDE-Protocols", "http,ftp");
group.writeEntry("X-KDE-ServiceTypes", "KParts/ReadOnlyPart,Browser/View,KParts/ReadWritePart");
group.writeEntry("MimeType", "text/plain;");
}
// faketextplugin: a ktexteditor plugin
if (!KService::serviceByDesktopPath("faketextplugin.desktop")) {
mustUpdateKSycoca = true;
}
const QString fakeTextplugin = KStandardDirs::locateLocal("services", "faketextplugin.desktop");
if (!QFile::exists(fakeTextplugin)) {
mustUpdateKSycoca = true;
KDesktopFile file(fakeTextplugin);
KConfigGroup group = file.desktopGroup();
group.writeEntry("Name", "FakeTextPlugin");
group.writeEntry("Type", "Service");
group.writeEntry("X-KDE-Library", "faketextplugin");
group.writeEntry("X-KDE-ServiceTypes", "KTextEditor/Plugin");
group.writeEntry("MimeType", "text/plain;");
}
if ( mustUpdateKSycoca ) {
// Update ksycoca in ~/.kde-unit-test after creating the above
QProcess::execute( KGlobal::dirs()->findExe(KBUILDSYCOCA_EXENAME), QStringList() << "--noincremental" );
kDebug() << "waiting for signal";
QVERIFY(QTest::kWaitForSignal(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), 10000));
kDebug() << "got signal";
}
}
void KServiceTest::cleanupTestCase()
{
// If I want the konqueror unit tests to work, then I better not have a non-working part
// as the preferred part for text/plain...
QStringList services; services << "fakeservice.desktop" << "fakepart.desktop" << "faketextplugin.desktop";
Q_FOREACH(const QString& service, services) {
const QString fakeService = KStandardDirs::locateLocal("services", service);
QFile::remove(fakeService);
}
//QProcess::execute( KGlobal::dirs()->findExe(KBUILDSYCOCA_EXENAME) );
KProcess proc;
proc << KStandardDirs::findExe(KBUILDSYCOCA_EXENAME);
proc.setOutputChannelMode(KProcess::MergedChannels); // silence kbuildsycoca output
proc.execute();
}
void KServiceTest::testByName()
{
if ( !KSycoca::isAvailable() )
QSKIP( "ksycoca not available", SkipAll );
KServiceType::Ptr s0 = KServiceType::serviceType("KParts/ReadOnlyPart");
QVERIFY( s0 );
QCOMPARE( s0->name(), QString::fromLatin1("KParts/ReadOnlyPart") );
KService::Ptr khtml = KService::serviceByDesktopPath("khtml.desktop");
QCOMPARE( khtml->name(), QString::fromLatin1("KHTML"));
}
void KServiceTest::testProperty()
{
KService::Ptr kdedkcookiejar = KService::serviceByDesktopPath("kded/kcookiejar.desktop");
QVERIFY(kdedkcookiejar);
QCOMPARE(kdedkcookiejar->entryPath(), QString("kded/kcookiejar.desktop"));
QCOMPARE(kdedkcookiejar->property("ServiceTypes").toStringList().join(","), QString("KDEDModule"));
QCOMPARE(kdedkcookiejar->property("X-KDE-Kded-autoload").toBool(), false);
QCOMPARE(kdedkcookiejar->property("X-KDE-Kded-load-on-demand").toBool(), true);
QVERIFY(!kdedkcookiejar->property("Name").toString().isEmpty());
QVERIFY(!kdedkcookiejar->property("Name[fr]", QVariant::String).isValid());
KService::Ptr kjavaappletviewer = KService::serviceByDesktopPath("kjavaappletviewer.desktop");
QVERIFY(kjavaappletviewer);
QCOMPARE(kjavaappletviewer->property("X-KDE-BrowserView-PluginsInfo").toString(), QString("kjava/pluginsinfo"));
// Test property("X-KDE-Protocols"), which triggers the KServiceReadProperty code.
KService::Ptr fakePart = KService::serviceByDesktopPath("fakepart.desktop");
QVERIFY(fakePart); // see initTestCase; it should be found.
QVERIFY(fakePart->propertyNames().contains("X-KDE-Protocols"));
const QStringList protocols = fakePart->property("X-KDE-Protocols").toStringList();
QCOMPARE(protocols, QStringList() << "http" << "ftp");
}
void KServiceTest::testAllServiceTypes()
{
if ( !KSycoca::isAvailable() )
QSKIP( "ksycoca not available", SkipAll );
const KServiceType::List allServiceTypes = KServiceType::allServiceTypes();
// A bit of checking on the allServiceTypes list itself
KServiceType::List::ConstIterator stit = allServiceTypes.begin();
const KServiceType::List::ConstIterator stend = allServiceTypes.end();
for ( ; stit != stend; ++stit ) {
const KServiceType::Ptr servtype = (*stit);
const QString name = servtype->name();
QVERIFY( !name.isEmpty() );
QVERIFY( servtype->sycocaType() == KST_KServiceType );
}
}
void KServiceTest::testAllServices()
{
if ( !KSycoca::isAvailable() )
QSKIP( "ksycoca not available", SkipAll );
const KService::List lst = KService::allServices();
QVERIFY( !lst.isEmpty() );
for ( KService::List::ConstIterator it = lst.begin();
it != lst.end(); ++it ) {
const KService::Ptr service = (*it);
QVERIFY( service->isType( KST_KService ) );
const QString name = service->name();
const QString entryPath = service->entryPath();
//kDebug() << name << "entryPath=" << entryPath << "menuId=" << service->menuId();
QVERIFY( !name.isEmpty() );
QVERIFY( !entryPath.isEmpty() );
KService::Ptr lookedupService = KService::serviceByDesktopPath( entryPath );
QVERIFY( lookedupService ); // not null
QCOMPARE( lookedupService->entryPath(), entryPath );
if ( service->isApplication() )
{
const QString menuId = service->menuId();
if ( menuId.isEmpty() )
qWarning( "%s has an empty menuId!", qPrintable( entryPath ) );
else if ( menuId == "kde4-konsole.desktop" )
m_hasKde4Konsole = true;
QVERIFY( !menuId.isEmpty() );
lookedupService = KService::serviceByMenuId( menuId );
QVERIFY( lookedupService ); // not null
QCOMPARE( lookedupService->menuId(), menuId );
}
}
}
// Helper method for all the trader tests
static bool offerListHasService( const KService::List& offers,
const QString& entryPath )
{
bool found = false;
KService::List::const_iterator it = offers.begin();
for ( ; it != offers.end() ; it++ )
{
if ( (*it)->entryPath() == entryPath ) {
if( found ) { // should be there only once
qWarning( "ERROR: %s was found twice in the list", qPrintable( entryPath ) );
return false; // make test fail
}
found = true;
}
}
return found;
}
void KServiceTest::testDBUSStartupType()
{
if ( !KSycoca::isAvailable() )
QSKIP( "ksycoca not available", SkipAll );
if ( !m_hasKde4Konsole )
QSKIP( "kde4-konsole.desktop not available", SkipAll );
//KService::Ptr konsole = KService::serviceByMenuId( "kde4-konsole.desktop" );
KService::Ptr konsole = KService::serviceByDesktopName( "konsole" );
QVERIFY(konsole);
QCOMPARE(konsole->menuId(), QString("kde4-konsole.desktop"));
//qDebug() << konsole->entryPath();
QCOMPARE((int)konsole->dbusStartupType(), (int)KService::DBusUnique);
}
void KServiceTest::testByStorageId()
{
if ( !KSycoca::isAvailable() )
QSKIP("ksycoca not available", SkipAll);
- if (!m_hasKde4Konsole)
- QSKIP("kdebase not installed", SkipAll);
- QVERIFY(KService::serviceByMenuId("kde4-systemsettings.desktop"));
- QVERIFY(!KService::serviceByMenuId("kde4-systemsettings")); // doesn't work, extension mandatory
- QVERIFY(KService::serviceByStorageId("kde4-systemsettings.desktop"));
- //QVERIFY(!KService::serviceByStorageId("kde4-systemsettings")); // doesn't work, extension mandatory; also shows a debug
+ QVERIFY(KService::serviceByMenuId("kde4-kmailservice.desktop"));
+ QVERIFY(!KService::serviceByMenuId("kde4-kmailservice")); // doesn't work, extension mandatory
+ QVERIFY(KService::serviceByStorageId("kde4-kmailservice.desktop"));
+ //QVERIFY(!KService::serviceByStorageId("kde4-kmailservice")); // doesn't work, extension mandatory; also shows a debug
+
// This one fails here; probably because there are two such files, so this would be too
// ambiguous... According to the testAllServices output, the entryPaths are
- // entryPath="/d/kde/inst/kde4/share/applications/kde4/systemsettings.desktop"
- // entryPath= "/usr/share/applications/kde/systemsettings.desktop"
+ // entryPath="/d/kde/inst/kde4/share/applications/kde4/kmailservice.desktop"
+ // entryPath= "/usr/share/applications/kde4/kmailservice.desktop"
//
- //QVERIFY(KService::serviceByDesktopPath("systemsettings.desktop"));
- QVERIFY(KService::serviceByDesktopName("systemsettings"));
- // Fails here, finds the kde3 systemsettings from /usr/share
- //QCOMPARE(KService::serviceByDesktopName("systemsettings")->menuId(), QString("kde4-systemsettings,desktop"));
+ //QVERIFY(KService::serviceByDesktopPath("kmailservice.desktop"));
+
+ QVERIFY(KService::serviceByDesktopName("kmailservice"));
+ // This could fail if it finds the kde3 kmailservice from /usr/share. But who still has kde3 :-)
+ QCOMPARE(KService::serviceByDesktopName("kmailservice")->menuId(), QString("kde4-kmailservice.desktop"));
}
void KServiceTest::testServiceTypeTraderForReadOnlyPart()
{
if ( !KSycoca::isAvailable() )
QSKIP( "ksycoca not available", SkipAll );
// Querying trader for services associated with KParts/ReadOnlyPart
KService::List offers = KServiceTypeTrader::self()->query("KParts/ReadOnlyPart");
QVERIFY( offers.count() > 0 );
//foreach( KService::Ptr service, offers )
// qDebug( "%s %s", qPrintable( service->name() ), qPrintable( service->entryPath() ) );
m_firstOffer = offers[0]->entryPath();
// Only test for parts provided by kdelibs, or better, by this unittest:
QVERIFY( offerListHasService( offers, "fakepart.desktop" ) );
QVERIFY( offerListHasService( offers, "kmultipart.desktop" ) );
QVERIFY( offerListHasService( offers, "khtml.desktop" ) );
QVERIFY( offerListHasService( offers, "khtmlimage.desktop" ) );
QVERIFY( offerListHasService( offers, "kjavaappletviewer.desktop" ) );
// Check ordering according to InitialPreference
int lastPreference = -1;
bool lastAllowedAsDefault = true;
Q_FOREACH(KService::Ptr service, offers) {
const QString path = service->entryPath();
const int preference = service->initialPreference(); // ## might be wrong if we use per-servicetype preferences...
//qDebug( "%s has preference %d, allowAsDefault=%d", qPrintable( path ), preference, service->allowAsDefault() );
if ( lastAllowedAsDefault && !service->allowAsDefault() ) {
// first "not allowed as default" offer
lastAllowedAsDefault = false;
lastPreference = -1; // restart
}
if ( lastPreference != -1 )
QVERIFY( preference <= lastPreference );
lastPreference = preference;
}
// Now look for any KTextEditor/Plugin
offers = KServiceTypeTrader::self()->query("KTextEditor/Plugin");
QVERIFY( offerListHasService( offers, "fakeservice.desktop" ) );
QVERIFY( offerListHasService( offers, "faketextplugin.desktop" ) );
}
void KServiceTest::testTraderConstraints()
{
if ( !KSycoca::isAvailable() )
QSKIP( "ksycoca not available", SkipAll );
KService::List offers = KServiceTypeTrader::self()->query("KTextEditor/Plugin", "Library == 'faketextplugin'");
QCOMPARE(offers.count(), 1);
QVERIFY( offerListHasService( offers, "faketextplugin.desktop" ) );
if (m_hasNonCLocale) {
// Test float parsing, must use dot as decimal separator independent of locale.
offers = KServiceTypeTrader::self()->query("KTextEditor/Plugin", "([X-KDE-Version] > 4.559) and ([X-KDE-Version] < 4.561)");
QCOMPARE(offers.count(), 1);
QVERIFY(offerListHasService( offers, "fakeservice.desktop"));
}
// A test with an invalid query, to test for memleaks
offers = KServiceTypeTrader::self()->query("KTextEditor/Plugin", "A == B OR C == D AND OR Foo == 'Parse Error'");
QVERIFY(offers.isEmpty());
}
void KServiceTest::testHasServiceType1() // with services constructed with a full path (rare)
{
QString fakepartPath = KStandardDirs::locate( "services", "fakepart.desktop" );
QVERIFY( !fakepartPath.isEmpty() );
KService fakepart( fakepartPath );
QVERIFY( fakepart.hasServiceType( "KParts/ReadOnlyPart" ) );
QVERIFY( fakepart.hasServiceType( "KParts/ReadWritePart" ) );
QString faketextPluginPath = KStandardDirs::locate( "services", "faketextplugin.desktop" );
QVERIFY( !faketextPluginPath.isEmpty() );
KService faketextPlugin( faketextPluginPath );
QVERIFY( faketextPlugin.hasServiceType( "KTextEditor/Plugin" ) );
QVERIFY( !faketextPlugin.hasServiceType( "KParts/ReadOnlyPart" ) );
}
void KServiceTest::testHasServiceType2() // with services coming from ksycoca
{
KService::Ptr fakepart = KService::serviceByDesktopPath( "fakepart.desktop" );
QVERIFY( !fakepart.isNull() );
QVERIFY( fakepart->hasServiceType( "KParts/ReadOnlyPart" ) );
QVERIFY( fakepart->hasServiceType( "KParts/ReadWritePart" ) );
KService::Ptr faketextPlugin = KService::serviceByDesktopPath( "faketextplugin.desktop" );
QVERIFY( !faketextPlugin.isNull() );
QVERIFY( faketextPlugin->hasServiceType( "KTextEditor/Plugin" ) );
QVERIFY( !faketextPlugin->hasServiceType( "KParts/ReadOnlyPart" ) );
}
void KServiceTest::testWriteServiceTypeProfile()
{
const QString serviceType = "KParts/ReadOnlyPart";
KService::List services, disabledServices;
services.append(KService::serviceByDesktopPath("khtmlimage.desktop"));
services.append(KService::serviceByDesktopPath("fakepart.desktop"));
disabledServices.append(KService::serviceByDesktopPath("khtml.desktop"));
KService::List::ConstIterator servit = services.constBegin();
for( ; servit != services.constEnd(); ++servit) {
QVERIFY(!servit->isNull());
}
KServiceTypeProfile::writeServiceTypeProfile( serviceType, services, disabledServices );
// Check that the file got written
QString profilerc = KStandardDirs::locateLocal( "config", "servicetype_profilerc" );
QVERIFY(!profilerc.isEmpty());
QVERIFY(QFile::exists(profilerc));
KService::List offers = KServiceTypeTrader::self()->query( serviceType );
QVERIFY( offers.count() > 0 ); // not empty
//foreach( KService::Ptr service, offers )
// qDebug( "%s %s", qPrintable( service->name() ), qPrintable( service->entryPath() ) );
QVERIFY( offers.count() >= 3 ); // at least 3, even
QCOMPARE( offers[0]->entryPath(), QString("khtmlimage.desktop") );
QCOMPARE( offers[1]->entryPath(), QString("fakepart.desktop") );
QVERIFY( offerListHasService( offers, "kmultipart.desktop" ) ); // should still be somewhere in there
QVERIFY( !offerListHasService( offers, "khtml.desktop" ) ); // it got disabled above
}
void KServiceTest::testDefaultOffers()
{
// Now that we have a user-profile, let's see if defaultOffers indeed gives us the default ordering.
const QString serviceType = "KParts/ReadOnlyPart";
KService::List offers = KServiceTypeTrader::self()->defaultOffers( serviceType );
QVERIFY( offers.count() > 0 ); // not empty
QVERIFY( offerListHasService( offers, "khtml.desktop" ) ); // it's here even though it's disabled in the profile
if ( m_firstOffer.isEmpty() )
QSKIP( "testServiceTypeTraderForReadOnlyPart not run", SkipAll );
QCOMPARE( offers[0]->entryPath(), m_firstOffer );
}
void KServiceTest::testDeleteServiceTypeProfile()
{
const QString serviceType = "KParts/ReadOnlyPart";
KServiceTypeProfile::deleteServiceTypeProfile( serviceType );
KService::List offers = KServiceTypeTrader::self()->query( serviceType );
QVERIFY( offers.count() > 0 ); // not empty
QVERIFY( offerListHasService( offers, "khtml.desktop" ) ); // it's back
if ( m_firstOffer.isEmpty() )
QSKIP( "testServiceTypeTraderForReadOnlyPart not run", SkipAll );
QCOMPARE( offers[0]->entryPath(), m_firstOffer );
}
void KServiceTest::testActionsAndDataStream()
{
const QString servicePath = KStandardDirs::locate( "services", "ScreenSavers/krandom.desktop" );
if (servicePath.isEmpty() )
QSKIP("kdebase not installed, krandom.desktop not found", SkipAll);
KService service( servicePath );
QVERIFY(!service.property("Name[fr]", QVariant::String).isValid());
const QList<KServiceAction> actions = service.actions();
QCOMPARE(actions.count(), 3);
const KServiceAction setupAction = actions[0];
QCOMPARE(setupAction.name(), QString("Setup"));
QCOMPARE(setupAction.exec(), QString("krandom.kss -setup"));
QVERIFY(!setupAction.icon().isEmpty());
QCOMPARE(setupAction.noDisplay(), false);
QVERIFY(!setupAction.isSeparator());
const KServiceAction rootAction = actions[2];
QCOMPARE(rootAction.name(), QString("Root"));
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
service.save(stream);
QVERIFY(!data.isEmpty());
// The binary size of that KService in ksycoca was 3700 when storing all Name[...] translations!
// Now down to 755. This is on x86, so make the assert for 1500 in case x86_64 needs more.
QVERIFY(data.size() < 1500);
QDataStream loadingStream(data);
// loading must first get type, see KSycocaEntryPrivate::save
// (the path that save writes out, is read by the KSycocaEntryPrivate ctor)
qint32 type;
loadingStream >> type;
KService loadedService(loadingStream, 0);
QCOMPARE(loadedService.name(), service.name());
QCOMPARE(loadedService.exec(), service.exec());
QCOMPARE(loadedService.actions().count(), 3);
}
void KServiceTest::testServiceGroups()
{
KServiceGroup::Ptr root = KServiceGroup::root();
QVERIFY(root);
qDebug() << root->groupEntries().count();
KServiceGroup::Ptr group = root;
QVERIFY(group);
const KServiceGroup::List list = group->entries(true /* sorted */,
true /* exclude no display entries */,
false /* allow separators */,
true /* sort by generic name */);
kDebug() << list.count();
Q_FOREACH(KServiceGroup::SPtr s, list) {
qDebug() << s->name() << s->entryPath();
}
// No unit test here yet, but at least this can be valgrinded for errors.
}
void KServiceTest::testKSycocaUpdate()
{
kWarning();
KService::Ptr fakeService = KService::serviceByDesktopPath("fakeservice.desktop");
QVERIFY(fakeService); // see initTestCase; it should be found.
// Test deleting a service
const QString servPath = KStandardDirs::locateLocal("services", "fakeservice.desktop");
QVERIFY(QFile::exists(servPath));
QSignalSpy spy(KSycoca::self(), SIGNAL(databaseChanged(QStringList)));
QVERIFY(spy.isValid());
QFile::remove(servPath);
kDebug() << QThread::currentThread() << "executing kbuildsycoca";
QProcess::execute( KGlobal::dirs()->findExe(KBUILDSYCOCA_EXENAME) );
kDebug() << QThread::currentThread() << "done";
while (spy.isEmpty())
QTest::qWait(50);
QVERIFY(!spy.isEmpty());
QVERIFY(!KService::serviceByDesktopPath("fakeservice.desktop")); // not in ksycoca anymore
QVERIFY(spy[0][0].toStringList().contains("services"));
kDebug() << QThread::currentThread() << "got signal ok";
spy.clear();
QVERIFY(fakeService); // the whole point of refcounting is that this KService instance is still valid.
QVERIFY(!QFile::exists(servPath));
// Recreate it, for future tests
createFakeService();
QVERIFY(QFile::exists(servPath));
kDebug() << QThread::currentThread() << "executing kbuildsycoca (2)";
QProcess::execute( KGlobal::dirs()->findExe(KBUILDSYCOCA_EXENAME) );
kDebug() << QThread::currentThread() << "done (2)";
while (spy.isEmpty())
QTest::qWait(50);
kDebug() << QThread::currentThread() << "got signal ok (2)";
QVERIFY(spy[0][0].toStringList().contains("services"));
if (QThread::currentThread() != QCoreApplication::instance()->thread())
m_sycocaUpdateDone.ref();
}
void KServiceTest::createFakeService()
{
const QString fakeService = KStandardDirs::locateLocal("services", "fakeservice.desktop");
KDesktopFile file(fakeService);
KConfigGroup group = file.desktopGroup();
group.writeEntry("Name", "FakePlugin");
group.writeEntry("Type", "Service");
group.writeEntry("X-KDE-Library", "fakeservice");
group.writeEntry("X-KDE-Version", "4.56");
group.writeEntry("ServiceTypes", "KTextEditor/Plugin");
group.writeEntry("MimeType", "text/plain;");
}
#include <QThreadPool>
#include <qtconcurrentrun.h>
// Testing for concurrent access to ksycoca from multiple threads
// It's especially interesting to run this test as ./kservicetest testThreads
// so that even the ksycoca initialization is happening from N threads at the same time.
// Use valgrind --tool=helgrind to see the race conditions.
void KServiceTest::testReaderThreads()
{
QThreadPool::globalInstance()->setMaxThreadCount(10);
QList<QFuture<void> > futures;
futures << QtConcurrent::run(this, &KServiceTest::testAllServices);
futures << QtConcurrent::run(this, &KServiceTest::testAllServices);
futures << QtConcurrent::run(this, &KServiceTest::testAllServices);
futures << QtConcurrent::run(this, &KServiceTest::testHasServiceType1);
futures << QtConcurrent::run(this, &KServiceTest::testAllServices);
futures << QtConcurrent::run(this, &KServiceTest::testAllServices);
Q_FOREACH(QFuture<void> f, futures) // krazy:exclude=foreach
f.waitForFinished();
QThreadPool::globalInstance()->setMaxThreadCount(1); // delete those threads
}
void KServiceTest::testThreads()
{
QThreadPool::globalInstance()->setMaxThreadCount(10);
QList<QFuture<void> > futures;
futures << QtConcurrent::run(this, &KServiceTest::testAllServices);
futures << QtConcurrent::run(this, &KServiceTest::testHasServiceType1);
futures << QtConcurrent::run(this, &KServiceTest::testKSycocaUpdate);
futures << QtConcurrent::run(this, &KServiceTest::testTraderConstraints);
while (m_sycocaUpdateDone == 0) // not using a bool, just to silence helgrind
QTest::qWait(100); // process D-Bus events!
kDebug() << "Joining all threads";
Q_FOREACH(QFuture<void> f, futures) // krazy:exclude=foreach
f.waitForFinished();
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Nov 1, 8:51 AM (1 d, 10 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
10075311
Default Alt Text
(25 KB)
Attached To
Mode
rKL kdelibs
Attached
Detach File
Event Timeline
Log In to Comment