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