File indexing completed on 2024-03-24 03:59:39
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2015 David Faure <faure@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include <KConfigGroup> 0009 #include <KDesktopFile> 0010 #include <QDebug> 0011 #include <QProcess> 0012 #include <QTemporaryDir> 0013 #include <QTest> 0014 #include <kservice.h> 0015 #include <kservicefactory_p.h> 0016 #include <ksycoca.h> 0017 #include <ksycoca_p.h> 0018 0019 // taken from tst_qstandardpaths 0020 #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_ANDROID) 0021 #define Q_XDG_PLATFORM 0022 #endif 0023 0024 class KSycocaXdgDirsTest : public QObject 0025 { 0026 Q_OBJECT 0027 0028 private Q_SLOTS: 0029 void initTestCase() 0030 { 0031 QStandardPaths::setTestModeEnabled(true); 0032 0033 QVERIFY(m_tempDir.isValid()); 0034 } 0035 void cleanupTestCase() 0036 { 0037 QFile::remove(KSycoca::absoluteFilePath()); 0038 } 0039 void testOtherAppDir(); 0040 0041 private: 0042 static void runKBuildSycoca(const QProcessEnvironment &environment); 0043 0044 QTemporaryDir m_tempDir; 0045 }; 0046 0047 QTEST_MAIN(KSycocaXdgDirsTest) 0048 0049 void KSycocaXdgDirsTest::runKBuildSycoca(const QProcessEnvironment &environment) 0050 { 0051 QProcess proc; 0052 const QString kbuildsycoca = QStringLiteral(KBUILDSYCOCAEXE); 0053 QVERIFY(!kbuildsycoca.isEmpty()); 0054 QStringList args; 0055 args << QStringLiteral("--testmode"); 0056 // proc.setProcessChannelMode(QProcess::ForwardedChannels); 0057 proc.start(kbuildsycoca, args); 0058 proc.setProcessEnvironment(environment); 0059 0060 proc.waitForFinished(); 0061 QCOMPARE(proc.exitStatus(), QProcess::NormalExit); 0062 } 0063 0064 // Ensure two apps with different XDG_DATA_DIRS/XDG_DATA_HOME don't use the same sycoca. 0065 void KSycocaXdgDirsTest::testOtherAppDir() 0066 { 0067 #ifndef Q_XDG_PLATFORM 0068 QSKIP("This test requires XDG_DATA_DIRS"); 0069 #endif 0070 0071 // KSycoca::self() represents application 1, running with one set of dirs 0072 KSycoca::self()->ensureCacheValid(); 0073 0074 // Create another xdg data dir 0075 const QString dataDir = m_tempDir.path(); 0076 qputenv("XDG_DATA_DIRS", QFile::encodeName(dataDir)); 0077 QCOMPARE(dataDir, QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation).constLast()); 0078 QVERIFY(!KService::serviceByDesktopPath(QStringLiteral("test_app_other.desktop"))); 0079 0080 const QString appDir = dataDir + QLatin1String{"/applications"}; 0081 0082 // The buildsystem copied applications.menus into bin/data/menus, so we don't rely on /etc/xdg 0083 const QByteArray modifiedConfigDirs = QFile::encodeName(QCoreApplication::applicationDirPath()) + "/data"; 0084 qputenv("XDG_CONFIG_DIRS", modifiedConfigDirs); 0085 0086 // test_app_other: live in a different application directory 0087 const QString testAppOther = appDir + QLatin1String{"/test_app_other.desktop"}; 0088 KDesktopFile file(testAppOther); 0089 KConfigGroup group = file.desktopGroup(); 0090 group.writeEntry("Type", "Application"); 0091 group.writeEntry("Exec", "kded5"); 0092 group.writeEntry("Name", "Test App Other"); 0093 qDebug() << "Just created" << testAppOther; 0094 file.sync(); 0095 0096 QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); 0097 env.insert(QStringLiteral("XDG_DATA_DIRS"), dataDir); 0098 runKBuildSycoca(env); 0099 0100 #if 0 // for debugging 0101 const KService::List lst = KService::allServices(); 0102 QVERIFY(!lst.isEmpty()); 0103 for (const KService::Ptr &serv : lst) { 0104 qDebug() << serv->entryPath() << serv->storageId() /*<< serv->desktopEntryName()*/; 0105 } 0106 #endif 0107 0108 // This is still NOT available to application 1. 0109 // kbuildsycoca created a different DB file, the one we read from hasn't changed. 0110 // Changing XDG_DATA_DIRS at runtime isn't supported, so this test isn't doing what apps would do. 0111 // The point however is that another app using different dirs cannot mess up our DB. 0112 QVERIFY(!KService::serviceByStorageId(QStringLiteral("test_app_other.desktop"))); 0113 0114 // Check here what the application 2 would see, by creating another sycoca instance. 0115 KSycoca otherAppSycoca; 0116 // do what serviceByStorageId does: 0117 otherAppSycoca.ensureCacheValid(); 0118 QVERIFY(otherAppSycoca.d->serviceFactory()->findServiceByStorageId(QStringLiteral("test_app_other.desktop"))); 0119 QVERIFY(otherAppSycoca.d->m_databasePath != KSycoca::self()->d->m_databasePath); // check that they use a different filename 0120 // check that the timestamp code works 0121 QVERIFY(!otherAppSycoca.d->needsRebuild()); 0122 } 0123 0124 #include "ksycoca_xdgdirstest.moc"