1 /*
2     SPDX-FileCopyrightText: 2008 Andreas Pakulat <apaku@gmx.de>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "test_sessioncontroller.h"
8 
9 #include <tests/autotestshell.h>
10 #include <tests/testcore.h>
11 
12 #include <KConfigGroup>
13 #include <KLocalizedString>
14 
15 #include "../core.h"
16 #include "../sessioncontroller.h"
17 #include "../session.h"
18 #include <QDebug>
19 #include <QFileInfo>
20 #include <QSignalSpy>
21 #include <QTest>
22 
23 using namespace KDevelop;
24 
25 //////////////////// Helper Functions ////////////////////////////////////////
26 
sessionDir(ISession * s)27 QString sessionDir( ISession* s )
28 {
29     return SessionController::sessionDirectory(s->id().toString());
30 }
31 
verifySessionDir(const QString & sessiondir,const QString & name,bool exists)32 void verifySessionDir( const QString& sessiondir, const QString& name, bool exists )
33 {
34     if( exists )
35     {
36         qDebug() << "checking existing session" << sessiondir;
37         QVERIFY( QFileInfo::exists( sessiondir ) );
38         QVERIFY( QFileInfo( sessiondir ).isDir() );
39         QVERIFY( QFileInfo::exists( sessiondir+"/sessionrc" ) );
40         KSharedConfigPtr cfg = KSharedConfig::openConfig( sessiondir+"/sessionrc" );
41         QCOMPARE( name, cfg->group("").readEntry( Session::cfgSessionNameEntry, "" ) );
42     } else {
43         qDebug() << "checking not-existing dir: " << sessiondir;
44         QVERIFY( !QFileInfo::exists( sessiondir ) );
45     }
46 }
47 
verifySessionDir(ISession * s,bool exists=true)48 void verifySessionDir( ISession* s, bool exists = true )
49 {
50     verifySessionDir(sessionDir(s), s->name(), exists);
51 }
52 
53 ////////////////////// Fixture ///////////////////////////////////////////////
54 
initTestCase()55 void TestSessionController::initTestCase()
56 {
57     AutoTestShell::init();
58     TestCore::initialize(Core::NoUi);
59     m_core = Core::self();
60     qRegisterMetaType<KDevelop::ISession*>();
61     qRegisterMetaType<KDevelop::Session*>();
62 }
63 
init()64 void TestSessionController::init()
65 {
66     m_sessionCtrl = m_core->sessionController();
67 }
68 
cleanupTestCase()69 void TestSessionController::cleanupTestCase()
70 {
71     const auto sessions = m_sessionCtrl->sessions();
72     for (const Session* session : sessions) {
73         TryLockSessionResult lock = m_sessionCtrl->tryLockSession(session->id().toString());
74         if (lock.lock)
75             m_sessionCtrl->deleteSession( lock.lock );
76     }
77 
78     TestCore::shutdown();
79 }
80 
createSession_data()81 void TestSessionController::createSession_data()
82 {
83     QTest::addColumn<QString>( "sessionName" );
84     QTest::newRow("SimpleName") << "TestSession";
85     QTest::newRow("NonLetterChars") << "Test%$Session";
86     QTest::newRow("NonAsciiChars") << QStringLiteral("TöstSession");
87 }
88 
createSession()89 void TestSessionController::createSession()
90 {
91     QFETCH(QString, sessionName);
92     int sessionCount = m_sessionCtrl->sessionNames().count();
93     Session* s = m_sessionCtrl->createSession( sessionName );
94     QVERIFY( m_sessionCtrl->sessionNames().contains( sessionName )  );
95     QCOMPARE( sessionCount+1, m_sessionCtrl->sessionNames().count() );
96     verifySessionDir( s );
97 }
98 
renameSession()99 void TestSessionController::renameSession()
100 {
101     const QString sessionName = QStringLiteral("TestSession4");
102     const QString newSessionName = QStringLiteral("TestOtherSession4");
103     KDevelop::Session *s = m_sessionCtrl->createSession( sessionName );
104     QCOMPARE( sessionName, s->name() );
105     verifySessionDir( s );
106     QSignalSpy spy(s, SIGNAL(sessionUpdated(KDevelop::ISession*)));
107     s->setName( newSessionName );
108     QCOMPARE( newSessionName, s->name() );
109     QCOMPARE( spy.size(), 1 );
110 
111     verifySessionDir( s );
112 }
113 
canRenameActiveSession()114 void TestSessionController::canRenameActiveSession()
115 {
116     const QString sessionName = QStringLiteral("TestSession5");
117     const QString newSessionName = QStringLiteral("TestOtherSession5");
118     KDevelop::Session *s = m_sessionCtrl->createSession( sessionName );
119     QCOMPARE( sessionName, s->name() );
120     m_sessionCtrl->loadSession( sessionName );
121     QSignalSpy spy(s, SIGNAL(sessionUpdated(KDevelop::ISession*)));
122     s->setName( newSessionName );
123     QCOMPARE( newSessionName, s->name() );
124     QCOMPARE( spy.size(), 1 );
125 
126     verifySessionDir( s );
127 }
128 
deleteSession()129 void TestSessionController::deleteSession()
130 {
131     const QString sessionName = QStringLiteral("TestSession3");
132     int sessionCount = m_sessionCtrl->sessionNames().count();
133     QPointer<Session> s = m_sessionCtrl->createSession( sessionName );
134     QString sessionId = s->id().toString();
135     QCOMPARE( sessionCount+1, m_sessionCtrl->sessionNames().count() );
136     verifySessionDir( s.data() );
137     const QString sessionDir = ::sessionDir(s);
138 
139     QSignalSpy spy(m_sessionCtrl, SIGNAL(sessionDeleted(QString)));
140     {
141         TryLockSessionResult lock = m_sessionCtrl->tryLockSession(sessionId);
142         QVERIFY(lock.lock);
143         m_sessionCtrl->deleteSession( lock.lock );
144     }
145     QCOMPARE( sessionCount, m_sessionCtrl->sessionNames().count() );
146     QVERIFY( !m_sessionCtrl->sessionNames().contains(sessionId) );
147 
148     QCOMPARE(spy.size(), 1);
149     QList<QVariant> arguments = spy.takeFirst();
150 
151     QString emittedSession = arguments.at(0).toString();
152     QCOMPARE( sessionId, emittedSession );
153 
154     verifySessionDir( sessionDir, sessionName, false );
155 }
156 
cloneSession()157 void TestSessionController::cloneSession()
158 {
159     QString sessionName = QStringLiteral("CloneableSession");
160     QString testgrp = QStringLiteral("TestGroup");
161     QString testentry = QStringLiteral("TestEntry");
162     QString testval = QStringLiteral("TestValue");
163     int sessionCount = m_sessionCtrl->sessionNames().count();
164     m_sessionCtrl->createSession( sessionName );
165     Session* s = m_sessionCtrl->session( sessionName );
166     s->config()->group( testgrp ).writeEntry( testentry, testval );
167     s->config()->sync();
168     QCOMPARE( sessionCount+1, m_sessionCtrl->sessionNames().count() );
169     QVERIFY( m_sessionCtrl->session( sessionName ) );
170 
171     QString newSession = m_sessionCtrl->cloneSession( sessionName );
172     QVERIFY( m_sessionCtrl->session( newSession ) );
173     QCOMPARE( sessionCount+2, m_sessionCtrl->sessionNames().count() );
174     Session* news = m_sessionCtrl->session( newSession );
175     QCOMPARE( testval, news->config()->group( testgrp ).readEntry( testentry, "" ) );
176     QCOMPARE( i18n( "Copy of %1", sessionName ), news->name() );
177 
178     verifySessionDir( news );
179 
180 
181 }
182 
readFromConfig()183 void TestSessionController::readFromConfig()
184 {
185     ISession* s = Core::self()->activeSession();
186     KConfigGroup grp( s->config(), "TestGroup" );
187     grp.writeEntry( "TestEntry", "Test1" );
188     KConfigGroup grp2( s->config(), "TestGroup" );
189     QCOMPARE(grp.readEntry( "TestEntry", "" ), QStringLiteral( "Test1" ) );
190 }
191 
temporary()192 void TestSessionController::temporary()
193 {
194     ISession* s = Core::self()->activeSession();
195     s->setTemporary(true);
196     const QString oldName = s->name();
197     const QString dir = sessionDir(s);
198 
199     verifySessionDir(s, true);
200     Core::self()->sessionController()->cleanup();
201     verifySessionDir(dir, oldName, false);
202     Core::self()->sessionController()->initialize(oldName);
203     QCOMPARE(Core::self()->activeSession()->name(), oldName);
204     // dir / UID can be different, hence don't verifySessionDir
205 }
206 
tryLockSession()207 void TestSessionController::tryLockSession()
208 {
209     const QString id1 = QUuid::createUuid().toString();
210     m_sessionCtrl->createSession( id1 )->setTemporary(true);
211     const QString id2 = QUuid::createUuid().toString();
212     m_sessionCtrl->createSession( id2 )->setTemporary(true);
213     {
214         // acquired scoped lock
215         QVERIFY(!SessionController::isSessionRunning(id1));
216         QCOMPARE(SessionController::sessionRunInfo(id1), SessionRunInfo());
217         TryLockSessionResult initial = SessionController::tryLockSession(id1);
218         QVERIFY(initial.lock);
219         QCOMPARE(initial.lock->id(), id1);
220         QCOMPARE(initial.runInfo, SessionRunInfo());
221         QVERIFY(SessionController::isSessionRunning(id1));
222 
223         SessionRunInfo info = SessionController::sessionRunInfo(id1);
224         QVERIFY(info != initial.runInfo);
225         QVERIFY(info.isRunning);
226         QCOMPARE(info.holderApp, QCoreApplication::applicationName());
227         QCOMPARE(info.holderPid, static_cast<int>(QCoreApplication::applicationPid()));
228 
229         // this should fail
230         TryLockSessionResult repeated = SessionController::tryLockSession(id1);
231         QVERIFY(!repeated.lock);
232         QCOMPARE(repeated.runInfo, info);
233 
234         // this should pass (different id)
235         QVERIFY(!SessionController::isSessionRunning(id2));
236         TryLockSessionResult other = SessionController::tryLockSession(id2);
237         QVERIFY(other.lock);
238         QCOMPARE(other.lock->id(), id2);
239         QCOMPARE(other.runInfo, SessionRunInfo());
240         QVERIFY(SessionController::isSessionRunning(id2));
241     }
242 
243     // scope left, sessions are now unlocked again
244     QVERIFY(!SessionController::isSessionRunning(id1));
245     QCOMPARE(SessionController::sessionRunInfo(id1), SessionRunInfo());
246     QVERIFY(!SessionController::isSessionRunning(id2));
247     QCOMPARE(SessionController::sessionRunInfo(id2), SessionRunInfo());
248 
249     // can re-lock it here
250     TryLockSessionResult final = SessionController::tryLockSession(id1);
251     QVERIFY(SessionController::isSessionRunning(id1));
252     QVERIFY(final.lock);
253     QCOMPARE(final.lock->id(), id1);
254     QCOMPARE(final.runInfo, SessionRunInfo());
255 }
256 
257 QTEST_GUILESS_MAIN(TestSessionController)
258