/*
* Copyright 2013-2015 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 3.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* Authors:
* Ying-Chun Liu (PaulLiu)
* Lukáš Tinkl
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "dbusunitysessionservice.h"
enum class Action : unsigned
{
LOGOUT = 0,
SHUTDOWN,
REBOOT,
NONE
};
class SessionBackendTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase() {
dbusUnitySession = new QDBusInterface ("com.canonical.Unity",
"/com/canonical/Unity/Session",
"com.canonical.Unity.Session",
QDBusConnection::sessionBus());
}
void init() {
qputenv("TEST_USER", "testuser");
qputenv("TEST_NOPASSWD_USERS", "");
}
void testUnitySessionLogoutRequested_data() {
QTest::addColumn("method");
QTest::addColumn("signal");
QTest::newRow("Logout") << "RequestLogout" << "LogoutRequested(bool)";
QTest::newRow("Reboot") << "RequestReboot" << "RebootRequested(bool)";
QTest::newRow("Shutdown") << "RequestShutdown" << "ShutdownRequested(bool)";
QTest::newRow("PromptLock") << "PromptLock" << "LockRequested()";
QTest::newRow("Lock") << "Lock" << "LockRequested()";
QTest::newRow("LockLightDM") << "Lock" << "Locked()"; // happens when we lock LightDM, only for Lock()
}
void testUnitySessionLogoutRequested() {
QFETCH(QString, method);
QFETCH(QString, signal);
DBusUnitySessionService dbusUnitySessionService;
QCoreApplication::processEvents(); // to let the service register on DBus
// .. because QSignalSpy checks the signal signature like this: "if (((aSignal[0] - '0') & 0x03) != QSIGNAL_CODE)"
QSignalSpy spy(&dbusUnitySessionService, qPrintable(signal.prepend(QSIGNAL_CODE)));
QDBusReply reply = dbusUnitySession->call(method);
QCOMPARE(reply.isValid(), true);
QTRY_COMPARE(spy.count(), 1);
}
void testGnomeSessionWrapperWithoutConfirmation_data() {
QTest::addColumn("method");
QTest::addColumn("signal");
QTest::newRow("Reboot") << "RequestReboot" << SIGNAL(RebootCalled(bool));
QTest::newRow("Shutdown") << "RequestShutdown" << SIGNAL(PowerOffCalled(bool));
}
void testGnomeSessionWrapperWithoutConfirmation() {
QFETCH(QString, method);
QFETCH(QString, signal);
DBusUnitySessionService dbusUnitySessionService;
DBusGnomeSessionManagerWrapper dbusGnomeSessionManagerWrapper;
QCoreApplication::processEvents(); // to let the services register on DBus
QDBusInterface login1Interface("org.freedesktop.login1",
"/logindsession",
"org.freedesktop.login1.Manager");
QSignalSpy spy(&login1Interface, signal.toUtf8().data());
QDBusInterface dbusGnomeSessionWrapper("org.gnome.SessionManager",
"/org/gnome/SessionManager",
"org.gnome.SessionManager",
QDBusConnection::sessionBus());
QVERIFY(dbusGnomeSessionWrapper.isValid());
QDBusReply reply = dbusGnomeSessionWrapper.call(method);
QVERIFY(reply.isValid());
QTRY_COMPARE(spy.count(), 1);
}
void testGnomeSessionWrapperWithConfirmation_data() {
QTest::addColumn("method");
QTest::addColumn("signal");
QTest::newRow("Reboot") << "Reboot" << SIGNAL(RebootRequested(bool));
QTest::newRow("Shutdown") << "Shutdown" << SIGNAL(ShutdownRequested(bool));
}
void testGnomeSessionWrapperWithConfirmation() {
QFETCH(QString, method);
QFETCH(QString, signal);
DBusUnitySessionService dbusUnitySessionService;
DBusGnomeSessionManagerWrapper dbusGnomeSessionManagerWrapper;
QCoreApplication::processEvents(); // to let the services register on DBus
QSignalSpy spy(&dbusUnitySessionService, signal.toUtf8().data());
QDBusInterface dbusGnomeSessionWrapper("org.gnome.SessionManager",
"/org/gnome/SessionManager",
"org.gnome.SessionManager",
QDBusConnection::sessionBus());
QVERIFY(dbusGnomeSessionWrapper.isValid());
QDBusReply reply = dbusGnomeSessionWrapper.call(method);
QVERIFY(reply.isValid());
QCOMPARE(spy.count(), 1);
}
void testGnomeSessionWrapperLogout_data() {
QTest::addColumn("mode");
QTest::addColumn("signal");
QTest::newRow("Logout") << 0 << SIGNAL(LogoutRequested(bool));
QTest::newRow("LogoutNoDialog") << 1 << SIGNAL(LogoutReady());
QTest::newRow("LogoutNoInhibits") << 2 << SIGNAL(LogoutReady());
QTest::newRow("LogoutNoDialogNoInhibits") << 3 << SIGNAL(LogoutReady());
}
void testGnomeSessionWrapperLogout() {
QFETCH(int, mode);
QFETCH(QString, signal);
DBusUnitySessionService dbusUnitySessionService;
DBusGnomeSessionManagerWrapper dbusGnomeSessionManagerWrapper;
QCoreApplication::processEvents(); // to let the services register on DBus
QSignalSpy spy(&dbusUnitySessionService, signal.toUtf8().data());
QDBusInterface dbusGnomeSessionWrapper("org.gnome.SessionManager",
"/org/gnome/SessionManager",
"org.gnome.SessionManager",
QDBusConnection::sessionBus());
QVERIFY(dbusGnomeSessionWrapper.isValid());
QDBusReply reply = dbusGnomeSessionWrapper.call("Logout", (quint32)mode);
QVERIFY(reply.isValid());
QCOMPARE(spy.count(), 1);
}
void testGnomeSessionDialogWrapper_data() {
QTest::addColumn("method");
QTest::addColumn("signal");
QTest::newRow("Logout") << (uint)Action::LOGOUT << "LogoutRequested(bool)";
QTest::newRow("Shutdown") << (uint)Action::SHUTDOWN << "ShutdownRequested(bool)";
QTest::newRow("Reboot") << (uint)Action::REBOOT << "RebootRequested(bool)";
}
void testGnomeSessionDialogWrapper() {
QFETCH(uint, method);
QFETCH(QString, signal);
DBusUnitySessionService dbusUnitySessionService;
QCoreApplication::processEvents(); // to let the service register on DBus
// Spy on the given signal on the /com/canonical/Unity/Session object
// as proof we are actually calling the actual method.
// .. because QSignalSpy checks the signal signature like this: "if (((aSignal[0] - '0') & 0x03) != QSIGNAL_CODE)"
QSignalSpy spy(&dbusUnitySessionService, qPrintable(signal.prepend(QSIGNAL_CODE)));
DBusGnomeSessionManagerDialogWrapper dbusGnomeSessionManagerDialogWrapper;
QCoreApplication::processEvents(); // to let the service register on DBus
QDBusInterface dbusGnomeSessionWrapper("com.canonical.Unity",
"/org/gnome/SessionManager/EndSessionDialog",
"org.gnome.SessionManager.EndSessionDialog",
QDBusConnection::sessionBus());
QCOMPARE(dbusGnomeSessionWrapper.isValid(), true);
// Set the QVariant as a QList type
QDbusList var;
QVariant inhibitors;
inhibitors.setValue(var);
QDBusReply reply = dbusGnomeSessionWrapper.call("Open", method, (unsigned)0, (unsigned)0, inhibitors);
QCOMPARE(reply.isValid(), true);
// Make sure we see the signal being emitted.
QCOMPARE(spy.count(), 1);
}
void testUnlockFromLogind() {
DBusUnitySessionService dbusUnitySessionService;
QCoreApplication::processEvents(); // to let the service register on DBus
QDBusInterface iface("org.freedesktop.login1", "/logindsession", "org.freedesktop.login1.Session");
QVERIFY(iface.isValid());
QSignalSpy spy(&dbusUnitySessionService, SIGNAL(Unlocked()));
QCOMPARE(iface.call("MockEmitUnlock").errorMessage(), QString());
QTRY_COMPARE(spy.count(), 1);
}
void testUserName() {
DBusUnitySessionService dbusUnitySessionService;
QCOMPARE(dbusUnitySessionService.UserName(), QString("testuser"));
}
void testRealName() {
DBusUnitySessionService dbusUnitySessionService;
QCoreApplication::processEvents(); // to let the service register on DBus
QDBusInterface accIface("org.freedesktop.Accounts", "/org/freedesktop/Accounts", "org.freedesktop.Accounts", QDBusConnection::systemBus());
if (accIface.isValid()) {
QDBusReply userPath = accIface.asyncCall("FindUserById", static_cast(geteuid()));
if (userPath.isValid()) {
QDBusInterface userAccIface("org.freedesktop.Accounts", userPath.value().path(), "org.freedesktop.Accounts.User", QDBusConnection::systemBus());
QCOMPARE(dbusUnitySessionService.RealName(), userAccIface.property("RealName").toString());
}
}
}
void testCanLock() {
DBusUnitySessionService dbusUnitySessionService;
qputenv("TEST_USER", "testuser");
QVERIFY(dbusUnitySessionService.CanLock());
qputenv("TEST_USER", "guest-abcdef"); // guest-* can't lock
QVERIFY(!dbusUnitySessionService.CanLock());
qputenv("TEST_USER", "testuser");
qputenv("TEST_NOPASSWD_USERS", "testuser"); // nopasswdlogin can't lock
QVERIFY(!dbusUnitySessionService.CanLock());
}
void testPromptLockRespectsCanLock() {
DBusUnitySessionService dbusUnitySessionService;
QSignalSpy spy(&dbusUnitySessionService, SIGNAL(lockRequested()));
QVERIFY(dbusUnitySessionService.CanLock());
dbusUnitySessionService.PromptLock();
QCOMPARE(spy.count(), 1);
spy.clear();
qputenv("TEST_USER", "guest-abcdef");
QVERIFY(!dbusUnitySessionService.CanLock());
dbusUnitySessionService.PromptLock();
QCOMPARE(spy.count(), 0);
}
private:
QDBusInterface *dbusUnitySession;
};
QTEST_GUILESS_MAIN(SessionBackendTest)
#include "sessionbackendtest.moc"