diff --git a/debian/applauncherd-testapps.install b/debian/applauncherd-testapps.install index b08c867..2d04f68 100644 --- a/debian/applauncherd-testapps.install +++ b/debian/applauncherd-testapps.install @@ -15,6 +15,7 @@ usr/bin/fala_wl.launch usr/bin/fala_wol usr/bin/fala_wol.sh usr/bin/fala_gettime +usr/bin/fala_gettime_ms usr/bin/fala_pixelchanged usr/share/dbus-1/services/com.nokia.fala_testapp.service usr/share/dbus-1/services/com.nokia.fala_wl.service diff --git a/debian/applauncherd-testscripts.install b/debian/applauncherd-testscripts.install index 4f4d375..0d5915a 100644 --- a/debian/applauncherd-testscripts.install +++ b/debian/applauncherd-testscripts.install @@ -4,6 +4,7 @@ usr/share/applauncherd-testscripts/check_pipes.py usr/share/applauncherd-testscripts/test-perf-mbooster.py usr/share/applauncherd-testscripts/tc_theming.rb usr/share/applauncherd-testscripts/test-perf.rb +usr/share/applauncherd-testscripts/get-coordinates.rb usr/share/applauncherd-testscripts/utils.py usr/share/applauncherd-testscripts/test-security.py usr/share/applauncherd-testscripts/fala_wid diff --git a/debian/changelog b/debian/changelog index b2f31df..10f499a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +applauncherd (0.15.2) unstable; urgency=low + + * Fixes: NB#205006 - Redundant(?) booster-monitor processes takes a lot of memory + * Changed: Modified startup time tests to support command line starting and parameters + + -- Alexey Shilov Tue, 23 Nov 2010 17:10:56 +0200 + applauncherd (0.15.1) stable; urgency=low * Fixes: NB#201779 - cheap way how to load all libraries correct diff --git a/src/launcherlib/CMakeLists.txt b/src/launcherlib/CMakeLists.txt index 73e981a..6b75fa6 100644 --- a/src/launcherlib/CMakeLists.txt +++ b/src/launcherlib/CMakeLists.txt @@ -7,8 +7,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/src/comm set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") # Set sources -set(SRC appdata.cpp booster.cpp boosterfactory.cpp monitorbooster.cpp connection.cpp daemon.cpp mbooster.cpp logger.cpp main.cpp qtbooster.cpp wrtbooster.cpp) -set(MOC_HDRS monitorbooster.h mbooster.h) +set(SRC appdata.cpp booster.cpp boosterfactory.cpp connection.cpp daemon.cpp mbooster.cpp logger.cpp main.cpp qtbooster.cpp wrtbooster.cpp) +set(MOC_HDRS mbooster.h wrtbooster.h) qt4_wrap_cpp(MOC_SRC ${MOC_HDRS}) # Use webruntime if found diff --git a/src/launcherlib/boosterfactory.cpp b/src/launcherlib/boosterfactory.cpp index 7c8efe6..713f45f 100644 --- a/src/launcherlib/boosterfactory.cpp +++ b/src/launcherlib/boosterfactory.cpp @@ -22,7 +22,6 @@ #include "mbooster.h" #include "qtbooster.h" #include "wrtbooster.h" -#include "monitorbooster.h" BoosterFactory::BoosterFactory() {} @@ -41,10 +40,6 @@ Booster * BoosterFactory::create(char type) { return new WRTBooster(); } - else if (type == MonitorBooster::type()) - { - return new MonitorBooster(); - } else { return NULL; @@ -65,10 +60,6 @@ void BoosterFactory::setProcessIdToBooster(char type, pid_t pid) { WRTBooster::setProcessId(pid); } - else if (type == MonitorBooster::type()) - { - MonitorBooster::setProcessId(pid); - } } char BoosterFactory::getBoosterTypeForPid(pid_t pid) @@ -85,10 +76,6 @@ char BoosterFactory::getBoosterTypeForPid(pid_t pid) { return WRTBooster::type(); } - else if (pid == MonitorBooster::processId()) - { - return MonitorBooster::type(); - } else { return 0; @@ -111,7 +98,6 @@ pid_t BoosterFactory::getBoosterPidForType(char type) } else { - // not used for MonitorBooster return 0; } } diff --git a/src/launcherlib/daemon.cpp b/src/launcherlib/daemon.cpp index 0655db4..1e81e37 100644 --- a/src/launcherlib/daemon.cpp +++ b/src/launcherlib/daemon.cpp @@ -24,7 +24,6 @@ #include "mbooster.h" #include "qtbooster.h" #include "wrtbooster.h" -#include "monitorbooster.h" #include "boosterfactory.h" #include @@ -148,7 +147,6 @@ void Daemon::run() forkBooster(MBooster::type()); forkBooster(QtBooster::type()); forkBooster(WRTBooster::type()); - forkBooster(MonitorBooster::type()); // Main loop while (true) @@ -160,58 +158,45 @@ void Daemon::run() ssize_t count = read(m_pipefd[0], reinterpret_cast(&msg), 1); if (count) { - // Read and store the pid of invoker if the message was not from - // a monitor booster it won't send the pid. - if (msg != MonitorBooster::type()) - { - // Read pid of peer invoker - pid_t invokerPid; - count = read(m_pipefd[0], reinterpret_cast(&invokerPid), sizeof(pid_t)); + // Read pid of peer invoker + pid_t invokerPid; + count = read(m_pipefd[0], reinterpret_cast(&invokerPid), sizeof(pid_t)); - if (count < static_cast(sizeof(pid_t))) - { - Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: pipe connection with booster failed"); - } - else - { - Logger::logInfo("Daemon: invoker's pid: %d \n", invokerPid); - } - - if (invokerPid != 0) - { - // Store booster - invoker pid pair - m_boosterPidToInvokerPid[BoosterFactory::getBoosterPidForType(msg)] = invokerPid; - } - - // Read booster respawn delay - int delay; - count = read(m_pipefd[0], reinterpret_cast(&delay), sizeof(int)); - - if (count < static_cast(sizeof(int))) - { - Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: pipe connection with booster failed"); - } - else - { - Logger::logInfo("Daemon: respawn delay: %d \n", delay); - } + if (count < static_cast(sizeof(pid_t))) + { + Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: pipe connection with booster failed"); + } + else + { + Logger::logInfo("Daemon: invoker's pid: %d \n", invokerPid); + } - // Fork a new booster of the given type + if (invokerPid != 0) + { + // Store booster - invoker pid pair + m_boosterPidToInvokerPid[BoosterFactory::getBoosterPidForType(msg)] = invokerPid; + } - // 2nd param guarantees some time for the just launched application - // to start up before forking new booster. Not doing this would - // slow down the start-up significantly on single core CPUs. + // Read booster respawn delay + int delay; + count = read(m_pipefd[0], reinterpret_cast(&delay), sizeof(int)); - forkBooster(msg, delay); + if (count < static_cast(sizeof(int))) + { + Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: pipe connection with booster failed"); } - // It was from a monitor booster, that means that theme / language has - // changed so we need to reset (kill) MBooster and WRTBooster. else { - // Kill MBooster and WRTBooster - killProcess(BoosterFactory::getBoosterPidForType(MBooster::type())); - killProcess(BoosterFactory::getBoosterPidForType(WRTBooster::type())); + Logger::logInfo("Daemon: respawn delay: %d \n", delay); } + + // Fork a new booster of the given type + + // 2nd param guarantees some time for the just launched application + // to start up before forking new booster. Not doing this would + // slow down the start-up significantly on single core CPUs. + + forkBooster(msg, delay); } else { diff --git a/src/launcherlib/mbooster.cpp b/src/launcherlib/mbooster.cpp index f667fa7..1775cae 100644 --- a/src/launcherlib/mbooster.cpp +++ b/src/launcherlib/mbooster.cpp @@ -35,7 +35,7 @@ int MBooster::m_ProcessID = 0; int MBooster::m_sighupFd[2]; struct sigaction MBooster::m_oldSigAction; -MBooster::MBooster() +MBooster::MBooster() : m_item(0) { // Install signals handler e.g. to exit cleanly if launcher dies. // This is a problem because MBooster runs a Qt event loop. @@ -149,12 +149,22 @@ bool MBooster::readCommand() // exit from event loop when invoker is ready to connect connect(this, SIGNAL(connectionAccepted()), MApplication::instance() , SLOT(quit())); + // enable theme change handler + m_item = new MGConfItem(MEEGOTOUCH_THEME_GCONF_KEY, 0); + connect(m_item, SIGNAL(valueChanged()), this, SLOT(notifyThemeChange())); + // start another thread to listen connection from invoker QtConcurrent::run(this, &MBooster::accept); // Run event loop so MApplication and MApplicationWindow objects can receive notifications MApplication::exec(); + // disable theme change handler + disconnect(m_item, 0, this, 0); + delete m_item; + m_item = NULL; + + // Restore signal handlers to previous values restoreUnixSignalHandlers(); @@ -174,6 +184,13 @@ bool MBooster::readCommand() return true; } +void MBooster::notifyThemeChange() +{ + MApplication::quit(); + ::_exit(EXIT_SUCCESS); +} + + void MBooster::accept() { if (m_conn->accept(m_app)) diff --git a/src/launcherlib/mbooster.h b/src/launcherlib/mbooster.h index 5a5605b..c736a1f 100644 --- a/src/launcherlib/mbooster.h +++ b/src/launcherlib/mbooster.h @@ -23,6 +23,7 @@ #include "booster.h" #include #include +#include #include using std::tr1::shared_ptr; @@ -118,6 +119,7 @@ private: //! yet transformed into a running application static const string m_temporaryProcessName; + //! wait for socket connection void accept(); //! Socket pair used to get SIGHUP @@ -129,11 +131,18 @@ private: //! Old sigaction struct static struct sigaction m_oldSigAction; + //! GConf item to listen theme change + MGConfItem* m_item; + private slots: //! Qt signal handler for SIGHUP. void handleSigHup(); + //! Qt signal handler for theme change + void notifyThemeChange(); + + signals: void connectionAccepted(); diff --git a/src/launcherlib/monitorbooster.cpp b/src/launcherlib/monitorbooster.cpp deleted file mode 100644 index 2592324..0000000 --- a/src/launcherlib/monitorbooster.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (directui@nokia.com) -** -** This file is part of applauncherd -** -** If you have questions regarding the use of this file, please contact -** Nokia at directui@nokia.com. -** -** This library is free software; you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation -** and appearing in the file LICENSE.LGPL included in the packaging -** of this file. -** -****************************************************************************/ - -#include -#include -#include - -#include "monitorbooster.h" -#include "mbooster.h" -#include "wrtbooster.h" -#include "logger.h" - -const string MonitorBooster::m_socketId = ""; -int MonitorBooster::m_ProcessID = 0; -const string MonitorBooster::m_temporaryProcessName = "booster-monitor"; - -MonitorBooster::MonitorBooster() -{ - // Add keys to listen to. - addKey(MEEGOTOUCH_THEME_GCONF_KEY); - addKey(MEEGOTOUCH_LANGUAGE_GCONF_KEY); -} - -void MonitorBooster::addKey(const QString & key) -{ - MGConfItem * item = new MGConfItem(key, 0); - m_gConfItems << QSharedPointer(item); - - QObject::connect(item, SIGNAL(valueChanged()), - this, SLOT(notifyKeyChange())); -} - -void MonitorBooster::run() -{ - int argc = 0; - QCoreApplication(argc, 0).exec(); -} - -void MonitorBooster::initialize(int initialArgc, char ** initialArgv, int newPipeFd[2]) -{ - setPipeFd(newPipeFd); - - // Clean-up all the env variables - clearenv(); - - // Rename process to temporary booster process name - renameProcess(initialArgc, initialArgv); -} - -void MonitorBooster::notifyKeyChange() -{ - // Signal the parent process that it can create a new - // waiting booster process and close write end - const char msg = boosterType(); - ssize_t ret = write(pipeFd(1), reinterpret_cast(&msg), 1); - if (ret == -1) { - Logger::logError("MonitorBooster: Couldn't send type message to launcher process\n"); - } -} - -char MonitorBooster::type() -{ - return 'k'; -} - -const string & MonitorBooster::socketName() -{ - return m_socketId; -} - -const string & MonitorBooster::socketId() const -{ - return m_socketId; -} - -void MonitorBooster::setProcessId(int pid) -{ - m_ProcessID = pid; -} - -int MonitorBooster::processId() -{ - return m_ProcessID; -} - -const string & MonitorBooster::temporaryProcessName() -{ - return m_temporaryProcessName; -} - -const string & MonitorBooster::boosterTemporaryProcessName() const -{ - return temporaryProcessName(); -} - -char MonitorBooster::boosterType() const -{ - return type(); -} - diff --git a/src/launcherlib/monitorbooster.h b/src/launcherlib/monitorbooster.h deleted file mode 100644 index ef67dec..0000000 --- a/src/launcherlib/monitorbooster.h +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (directui@nokia.com) -** -** This file is part of applauncherd -** -** If you have questions regarding the use of this file, please contact -** Nokia at directui@nokia.com. -** -** This library is free software; you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation -** and appearing in the file LICENSE.LGPL included in the packaging -** of this file. -** -****************************************************************************/ - -#ifndef MONITORBOOSTER_H -#define MONITORBOOSTER_H - -#include -#include -#include -#include "booster.h" - -class QString; - -/*! \class MonitorBooster - * - * MonitorBooster kills certain boosters e.g. when themeing or language changes. - * Daemon will then restart the boosters. - */ -class MonitorBooster : public QObject, public Booster -{ - Q_OBJECT - - public: - - //! Constructor. - MonitorBooster(); - - /*! - * \brief Return the empty strung (not used in MonitorBooster). - * \return empty string. - */ - static const string & socketName(); - - //! Add a GConf key to trigger booster process termination - void addKey(const QString & key); - - /*! Starts the killer. This will initialize a QCoreApplication, does - * not return. reimp. - */ - virtual void run(); - - //! \reimp - virtual char boosterType() const; - - //! \reimp - virtual void initialize(int initialArgc, char ** initialArgv, int pipeFd[2]); - - /*! - * \brief Return a unique character ('k') represtenting the type of MonitorBooster. - * \return Type character. - */ - static char type(); - - /*! - * \brief Keep booster pid, should be reset before booster run application's main() function - */ - static void setProcessId(int pid); - - /*! - * \brief Return booster pid - */ - static int processId(); - - //! Return the artificial process name - static const string & temporaryProcessName(); - - //! \reimp - virtual const string & boosterTemporaryProcessName() const; - -protected: - - //! \reimp - virtual const string & socketId() const; - -private Q_SLOTS: - - //! Send message to main process that something has changed - void notifyKeyChange(); - -private: - - static const string m_socketId; - static int m_ProcessID; - - //! Process name to be used for booster - static const string m_temporaryProcessName; - - QList > m_gConfItems; -}; - -#endif // MONITORBOOSTER_H diff --git a/src/launcherlib/wrtbooster.cpp b/src/launcherlib/wrtbooster.cpp index 7033b98..10f71fd 100644 --- a/src/launcherlib/wrtbooster.cpp +++ b/src/launcherlib/wrtbooster.cpp @@ -19,6 +19,12 @@ #include "wrtbooster.h" #include "logger.h" +#include "connection.h" + +#include +#include +#include + #ifdef HAVE_MCOMPONENTCACHE #include @@ -31,6 +37,69 @@ const string WRTBooster::m_socketId = "/tmp/boostw"; const string WRTBooster::m_temporaryProcessName = "booster-w"; int WRTBooster::m_ProcessID = 0; +int WRTBooster::m_sighupFd[2]; +struct sigaction WRTBooster::m_oldSigAction; + +WRTBooster::WRTBooster() : m_item(0) +{ + // Install signals handler e.g. to exit cleanly if launcher dies. + // This is a problem because WRTBooster runs a Qt event loop. + setupUnixSignalHandlers(); + + // Create socket pair for SIGTERM + if (::socketpair(AF_UNIX, SOCK_STREAM, 0, m_sighupFd)) + { + Logger::logError("Couldn't create HUP socketpair"); + } + else + { + // Install a socket notifier on the socket + m_snHup.reset(new QSocketNotifier(m_sighupFd[1], QSocketNotifier::Read, this)); + connect(m_snHup.get(), SIGNAL(activated(int)), this, SLOT(handleSigHup())); + } +} + +// +// All this signal handling code is taken from Qt's Best Practices: +// http://doc.qt.nokia.com/latest/unix-signals.html +// + +void WRTBooster::hupSignalHandler(int) +{ + char a = 1; + ::write(m_sighupFd[0], &a, sizeof(a)); +} + +void WRTBooster::handleSigHup() +{ + ::_exit(EXIT_SUCCESS); +} + +bool WRTBooster::setupUnixSignalHandlers() +{ + struct sigaction hup; + + hup.sa_handler = WRTBooster::hupSignalHandler; + sigemptyset(&hup.sa_mask); + hup.sa_flags |= SA_RESTART; + + if (sigaction(SIGHUP, &hup, &m_oldSigAction) > 0) + { + return false; + } + + return true; +} + +bool WRTBooster::restoreUnixSignalHandlers() +{ + if (sigaction(SIGHUP, &m_oldSigAction, 0) > 0) + { + return false; + } + + return true; +} const string & WRTBooster::socketId() const { @@ -78,3 +147,61 @@ int WRTBooster::processId() { return m_ProcessID; } + +bool WRTBooster::readCommand() +{ + // Setup the conversation channel with the invoker. + m_conn = new Connection(socketId()); + + // exit from event loop when invoker is ready to connect + connect(this, SIGNAL(connectionAccepted()), MApplication::instance() , SLOT(quit())); + + // enable theme change handler + m_item = new MGConfItem(MEEGOTOUCH_THEME_GCONF_KEY, 0); + connect(m_item, SIGNAL(valueChanged()), this, SLOT(notifyThemeChange())); + + // start another thread to listen connection from invoker + QtConcurrent::run(this, &WRTBooster::accept); + + // Run event loop so MApplication and MApplicationWindow objects can receive notifications + MApplication::exec(); + + // disable theme change handler + disconnect(m_item, 0, this, 0); + delete m_item; + m_item = NULL; + + + // Restore signal handlers to previous values + restoreUnixSignalHandlers(); + + // Receive application data from the invoker + if(!m_conn->receiveApplicationData(m_app)) + { + m_conn->close(); + return false; + } + + // Close the connection if exit status doesn't need + // to be sent back to invoker + if (!m_conn->isReportAppExitStatusNeeded()) + { + m_conn->close(); + } + return true; +} + +void WRTBooster::notifyThemeChange() +{ + MApplication::quit(); + ::_exit(EXIT_SUCCESS); +} + + +void WRTBooster::accept() +{ + if (m_conn->accept(m_app)) + { + emit connectionAccepted(); + } +} diff --git a/src/launcherlib/wrtbooster.h b/src/launcherlib/wrtbooster.h index e5901d9..57e22a3 100644 --- a/src/launcherlib/wrtbooster.h +++ b/src/launcherlib/wrtbooster.h @@ -21,6 +21,14 @@ #define WRTBOOSTER_H #include "booster.h" +#include +#include +#include +#include + +using std::tr1::shared_ptr; + +#include /*! \class WRTBooster @@ -30,12 +38,14 @@ similarly to MBooster. However, the cache content is optimized for web runtime's use. */ -class WRTBooster : public Booster +class WRTBooster : public QObject, public Booster { + Q_OBJECT + public: //! \brief Constructor - WRTBooster() {}; + WRTBooster(); //! \brief Destructor virtual ~WRTBooster() {}; @@ -75,11 +85,25 @@ public: */ static int processId(); + //! UNIX signal handler for SIGHUP + static void hupSignalHandler(int unused); + + //! Setup UNIX signal handlers + static bool setupUnixSignalHandlers(); + + //! Restore UNIX signal handlers to previous values + static bool restoreUnixSignalHandlers(); + + protected: //! \reimp virtual const string & socketId() const; + //! \reimp + virtual bool readCommand(); + + private: //! Disable copy-constructor @@ -96,6 +120,35 @@ private: //! yet transformed into a running application static const string m_temporaryProcessName; + //! wait for socket connection + void accept(); + + //! Socket pair used to get SIGHUP + static int m_sighupFd[2]; + + //! Socket notifier used for m_sighupFd + shared_ptr m_snHup; + + //! Old sigaction struct + static struct sigaction m_oldSigAction; + + //! GConf item to listen theme change + MGConfItem* m_item; + +private slots: + + //! Qt signal handler for SIGHUP. + void handleSigHup(); + + //! Qt signal handler for theme change + void notifyThemeChange(); + + +signals: + + void connectionAccepted(); + + #ifdef UNIT_TEST friend class Ut_WRTBooster; #endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5b3e64e..6e0160d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -46,6 +46,9 @@ add_subdirectory(Common/TestApps/themetest) # Sub build: Common/TestApps/fala_gettime add_subdirectory(Common/TestApps/fala_gettime) +# Sub build: Common/TestApps/fala_gettime_ms +add_subdirectory(Common/TestApps/fala_gettime_ms) + # Sub build: Common/TestApps/helloworld add_subdirectory(Common/TestApps/helloworld) diff --git a/tests/Common/TestApps/fala_gettime_ms/CMakeLists.txt b/tests/Common/TestApps/fala_gettime_ms/CMakeLists.txt new file mode 100644 index 0000000..1d47822 --- /dev/null +++ b/tests/Common/TestApps/fala_gettime_ms/CMakeLists.txt @@ -0,0 +1,13 @@ +# Set sources +set(SRC fala_gettime_ms.cpp) + +set(CMAKE_CXX_FLAGS "-O3") + +# Link statically to minimize startup time. +set(CMAKE_EXE_LINKER_FLAGS "-static") + +add_executable(fala_gettime_ms ${SRC}) + +# Install +install(PROGRAMS fala_gettime_ms DESTINATION /usr/bin/) + diff --git a/tests/Common/TestApps/fala_gettime_ms/fala_gettime_ms.cpp b/tests/Common/TestApps/fala_gettime_ms/fala_gettime_ms.cpp new file mode 100644 index 0000000..527f1a0 --- /dev/null +++ b/tests/Common/TestApps/fala_gettime_ms/fala_gettime_ms.cpp @@ -0,0 +1,18 @@ +#include +#include +#include +#include + + +int main(int argc, char **argv) { + timeval tim; + gettimeofday(&tim, NULL); + if (argc > 0) { + printf("%d%03d %s\n", + static_cast(tim.tv_sec), static_cast(tim.tv_usec/1000), argv[1]); + } else { + printf("%d%03d\n", + static_cast(tim.tv_sec), static_cast(tim.tv_usec/1000)); + } + return true; +} diff --git a/tests/Common/unittests/ut_boosterfactory/CMakeLists.txt b/tests/Common/unittests/ut_boosterfactory/CMakeLists.txt index 4381835..cb8e934 100644 --- a/tests/Common/unittests/ut_boosterfactory/CMakeLists.txt +++ b/tests/Common/unittests/ut_boosterfactory/CMakeLists.txt @@ -1,10 +1,10 @@ set(LAUNCHER ${CMAKE_HOME_DIRECTORY}/src/launcherlib) # Set sources -set(SRC ut_boosterfactory.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/monitorbooster.cpp ${LAUNCHER}/wrtbooster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp) +set(SRC ut_boosterfactory.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp) # Set moc headers -set(MOC_HDRS ut_boosterfactory.h ${LAUNCHER}/monitorbooster.h ${LAUNCHER}/mbooster.h) +set(MOC_HDRS ut_boosterfactory.h ${LAUNCHER}/mbooster.h ${LAUNCHER}/wrtbooster.h) # Run moc qt4_wrap_cpp(MOC_SRC ${MOC_HDRS}) diff --git a/tests/Common/unittests/ut_boosterfactory/ut_boosterfactory.cpp b/tests/Common/unittests/ut_boosterfactory/ut_boosterfactory.cpp index 332d536..310870d 100644 --- a/tests/Common/unittests/ut_boosterfactory/ut_boosterfactory.cpp +++ b/tests/Common/unittests/ut_boosterfactory/ut_boosterfactory.cpp @@ -23,7 +23,6 @@ #include "mbooster.h" #include "qtbooster.h" #include "wrtbooster.h" -#include "monitorbooster.h" void Ut_BoosterFactory::initTestCase() {} @@ -45,14 +44,10 @@ void Ut_BoosterFactory::testCreate() QVERIFY(dynamic_cast(booster)); delete booster; - booster = BoosterFactory::create('k'); - QVERIFY(dynamic_cast(booster)); - delete booster; - for (int i = 0; i < 256; i++) { unsigned char t = static_cast(i); - if (t != 'q' && t != 'm' && t != 'w' && t != 'k') + if (t != 'q' && t != 'm' && t != 'w') { QVERIFY(!BoosterFactory::create(t)); } @@ -76,19 +71,17 @@ void Ut_BoosterFactory::testGetBoosterTypeForPid() BoosterFactory::setProcessIdToBooster('q', 1); BoosterFactory::setProcessIdToBooster('m', 2); BoosterFactory::setProcessIdToBooster('w', 3); - BoosterFactory::setProcessIdToBooster('k', 4); QVERIFY(BoosterFactory::getBoosterTypeForPid(1) == 'q'); QVERIFY(BoosterFactory::getBoosterTypeForPid(2) == 'm'); QVERIFY(BoosterFactory::getBoosterTypeForPid(3) == 'w'); - QVERIFY(BoosterFactory::getBoosterTypeForPid(4) == 'k'); QVERIFY(BoosterFactory::getBoosterTypeForPid(0) == 0); for (int i = 0; i < 256; i++) { unsigned char t = static_cast(i); - if (t != 'q' && t != 'm' && t != 'w' && t != 'k') + if (t != 'q' && t != 'm' && t != 'w') { BoosterFactory::setProcessIdToBooster(t, 1000); QVERIFY(BoosterFactory::getBoosterTypeForPid(1000) == 0); @@ -101,17 +94,15 @@ void Ut_BoosterFactory::testGetBoosterPidForType() BoosterFactory::setProcessIdToBooster('q', 145); BoosterFactory::setProcessIdToBooster('m', 245); BoosterFactory::setProcessIdToBooster('w', 345); - BoosterFactory::setProcessIdToBooster('k', 445); QVERIFY(BoosterFactory::getBoosterPidForType('q') == 145); QVERIFY(BoosterFactory::getBoosterPidForType('m') == 245); QVERIFY(BoosterFactory::getBoosterPidForType('w') == 345); - QVERIFY(BoosterFactory::getBoosterPidForType('k') == 0); // shouldn't be used!!! for (int i = 0; i < 256; i++) { unsigned char t = static_cast(i); - if (t != 'q' && t != 'm' && t != 'w' && t != 'k') + if (t != 'q' && t != 'm' && t != 'w') { QVERIFY(BoosterFactory::getBoosterPidForType(t) == 0); } diff --git a/tests/Common/unittests/ut_connection/CMakeLists.txt b/tests/Common/unittests/ut_connection/CMakeLists.txt index 8951b40..be92b27 100644 --- a/tests/Common/unittests/ut_connection/CMakeLists.txt +++ b/tests/Common/unittests/ut_connection/CMakeLists.txt @@ -1,10 +1,10 @@ set(LAUNCHER ${CMAKE_HOME_DIRECTORY}/src/launcherlib) # Set sources -set(SRC ut_connection.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/monitorbooster.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp) +set(SRC ut_connection.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp) # Set moc headers -set(MOC_HDRS ut_connection.h ${LAUNCHER}/monitorbooster.h ${LAUNCHER}/mbooster.h) +set(MOC_HDRS ut_connection.h ${LAUNCHER}/mbooster.h ${LAUNCHER}/wrtbooster.h) # Set the program name define used in daemon.cpp set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROG_NAME_LAUNCHER=\\\"applauncherd\\\"") diff --git a/tests/Common/unittests/ut_daemon/CMakeLists.txt b/tests/Common/unittests/ut_daemon/CMakeLists.txt index fb78553..bf6f66d 100644 --- a/tests/Common/unittests/ut_daemon/CMakeLists.txt +++ b/tests/Common/unittests/ut_daemon/CMakeLists.txt @@ -1,9 +1,9 @@ # Set sources set(LAUNCHER ${CMAKE_HOME_DIRECTORY}/src/launcherlib) -set(SRC ut_daemon.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/monitorbooster.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp) +set(SRC ut_daemon.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp) # Set moc headers -set(MOC_HDRS ut_daemon.h ${LAUNCHER}/monitorbooster.h ${LAUNCHER}/mbooster.h) +set(MOC_HDRS ut_daemon.h ${LAUNCHER}/mbooster.h ${LAUNCHER}/wrtbooster.h) # Set the program name define used in daemon.cpp set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROG_NAME_LAUNCHER=\\\"applauncherd\\\"") diff --git a/tests/Common/unittests/ut_wrtbooster/CMakeLists.txt b/tests/Common/unittests/ut_wrtbooster/CMakeLists.txt index 357724b..0a5c8ed 100644 --- a/tests/Common/unittests/ut_wrtbooster/CMakeLists.txt +++ b/tests/Common/unittests/ut_wrtbooster/CMakeLists.txt @@ -5,7 +5,7 @@ set(SRC ut_wrtbooster.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUN ${LAUNCHER}/logger.cpp ${LAUNCHER}/wrtbooster.cpp) # Set moc headers -set(MOC_HDRS ut_wrtbooster.h) +set(MOC_HDRS ut_wrtbooster.h ${LAUNCHER}/wrtbooster.h) # Run moc qt4_wrap_cpp(MOC_SRC ${MOC_HDRS}) diff --git a/tests/Harmattan/TestScripts/CMakeLists.txt b/tests/Harmattan/TestScripts/CMakeLists.txt index 1be8dbd..6726d88 100644 --- a/tests/Harmattan/TestScripts/CMakeLists.txt +++ b/tests/Harmattan/TestScripts/CMakeLists.txt @@ -9,6 +9,7 @@ install(FILES install(PROGRAMS ts_prestartapp.rb tc_theming.rb + get-coordinates.rb test-perf.rb fala_wid fala_xres_wl diff --git a/tests/Harmattan/TestScripts/get-coordinates.rb b/tests/Harmattan/TestScripts/get-coordinates.rb new file mode 100755 index 0000000..ac2f5e0 --- /dev/null +++ b/tests/Harmattan/TestScripts/get-coordinates.rb @@ -0,0 +1,106 @@ +#!/usr/bin/ruby +# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# Contact: Nokia Corporation (directui@nokia.com) +# +# This file is part of applauncherd. +# +# If you have questions regarding the use of this file, please contact +# Nokia at directui@nokia.com. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation +# and appearing in the file LICENSE.LGPL included in the packaging +# of this file. +# +# * Description: Performance Test for applauncherd +# +# * Objectives: test the startup time for applications +# + +require 'tdriver' +require 'date' +require 'optparse' + +include TDriverVerify + +options = {} + +optparse = OptionParser.new do|opts| + # Set a banner, displayed at the top + # of the help screen. + opts.banner = "Usage: get-coordinates.rb [options] " + + options[:application] = nil + opts.on( '-a', '--application APP', 'Application name in application grid' ) do|app| + options[:application] = app + end + + options[:grid] = false + opts.on( '-g', '--grid_only', 'Only make application grid visible, not find any coordinates ' ) do + options[:grid] = true + end + + # This displays the help screen, all programs are + # assumed to have this option. + opts.on( '-h', '--help', 'Display this screen' ) do + puts opts + exit 0 + end + +end + +optparse.parse! + + +if options[:application] == nil && !(options[:grid]) + puts "Application name not defined!" + exit 1 +end + + + +pos = 0 +appName=options[:application] +sut = TDriver.sut(:Id=> 'sut_qt_maemo') +appOnTop = sut.application() + +while appOnTop.attribute('objectName') != 'meegotouchhome' + fullName = appOnTop.attribute('FullName') + +# puts "Now killing #{fullName} from the top" + system "pkill #{fullName}" + appOnTop = sut.application() +end + +# Application grid should be now visible +if options[:grid] + exit 0; +end + +@meegoHome = sut.application(:name => 'meegotouchhome') + + +sleep(2) +if @meegoHome.test_object_exists?("LauncherButton", :text => appName) + icon = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName) + while icon.attribute('visibleOnScreen') == 'false' || @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName).attribute('y').to_i > 400 + @meegoHome.Launcher.MPannableViewport( :name => 'SwipePage' ).MWidget( :name => 'glass' ).gesture(:Up, 1, 300) + sleep(0.2) + icon.refresh + end + xpos = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName).attribute('x') + ypos = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName).attribute('y') + @pos = "#{xpos}x#{ypos}" + + print @pos + exit 0 +else + #icon does not + #raise error and exit + raise "Application not found in Application grid" + exit 1 +end + + diff --git a/tests/Harmattan/TestScripts/test-perf.rb b/tests/Harmattan/TestScripts/test-perf.rb index 7f637a0..ac9001d 100755 --- a/tests/Harmattan/TestScripts/test-perf.rb +++ b/tests/Harmattan/TestScripts/test-perf.rb @@ -19,161 +19,185 @@ # * Objectives: test the startup time for applications # -require 'tdriver' +#require 'tdriver' require 'date' require 'test/unit' -include TDriverVerify - +require 'optparse' class TC_PerformanceTests < Test::Unit::TestCase - COUNT = 3 - APP_WITH_LAUNCHER = 'fala_wl' - APP_WITHOUT_LAUNCHER = 'fala_wol' - PIXELCHANGED_BINARY= '/usr/bin/fala_pixelchanged' - TEST_SCRIPT_LOCATION = '/usr/share/applauncherd-testscripts' - PIXELCHANGED_LOG = '/tmp/fala_pixelchanged.log' - @start_time = 0 - @end_time = 0 - @pos = 0 - - $path = string = `echo $PATH ` - - # method called before any test case - def setup + COUNT = 3 + PIXELCHANGED_BINARY= '/usr/bin/fala_pixelchanged' + TEST_SCRIPT_LOCATION = '/usr/share/applauncherd-testscripts' + GET_COORDINATES_SCRIPT="#{TEST_SCRIPT_LOCATION}/get-coordinates.rb" + PIXELCHANGED_LOG = '/tmp/fala_pixelchanged.log' + FALA_GETTIME_BINARY = '/usr/bin/fala_gettime_ms' + @start_time = 0 + @end_time = 0 + @pos = 0 + @options = {} + - @sut = TDriver.sut(:Id=> 'sut_qt_maemo') - if $path.include?("scratchbox") - puts "Inside SB, Do Nothing to unlock" - else - system "mcetool --set-tklock-mode=unlocked" + $path = string = `echo $PATH ` + + # method called before any test case + def setup + + optparse = OptionParser.new do|opts| + options = {} + # Set a banner, displayed at the top + # of the help screen. + opts.banner = "Usage: get-coordinates.rb [options] " + + options[:application] = nil + opts.on( '-a', '--application APP', 'Application name in application grid' ) do|app| + options[:application] = app + end - # restart duihome so that qttasserver notices it - # NOTE: Remove the cludge after duihome -> meegotouchhome renaming is complete - if not system("/sbin/initctl restart xsession/duihome") - system("/sbin/initctl restart xsession/mthome") - end + options[:command] = nil + opts.on( '-c', '--command_line COMMAND', 'Start application from witc COMMAND from command line instead of grid.' ) do|command| + options[:command] = command + end - system("initctl stop xsession/sysuid") - system("initctl stop xsession/applifed") - + options[:limit] = nil + opts.on( '-l', '--limit MILLISECONDS', 'Time limit in milliseconds. Slower startup will make test to fail.' ) do|milliseconds| + options[:limit] = milliseconds.to_i + end + + opts.on( '-h', '--help', 'Display this screen' ) do + puts opts + exit 0 + end + @options=options + end - end + optparse.parse! + - + if @options[:application] == nil && @options[:command] == nil + puts "Application not defined!" + exit 1 end - # method called after any test case for cleanup purposes - def teardown - puts "exit from teardown" - system("initctl start xsession/sysuid") - system("initctl start xsession/applifed") + if @options[:command] != nil + puts "#{@options[:command]}" end - def open_Apps(appName) - #Remove the Log file if it exists - if FileTest.exists?(PIXELCHANGED_LOG) - system "rm #{PIXELCHANGED_LOG}" - end - appOnTop = @sut.application() - while appOnTop.attribute('objectName') != 'meegotouchhome' - fullName = appOnTop.attribute('FullName') - puts "Now killing #{fullName} from the top" - system "pkill #{fullName}" - appOnTop = @sut.application() - end - - #Open the Application from the application grid - begin - @meegoHome = @sut.application(:name => 'duihome') - rescue MobyBase::TestObjectNotFoundError - @meegoHome = @sut.application(:name => 'meegotouchhome') - end - - sleep(2) - if @meegoHome.test_object_exists?("LauncherButton", :text => appName) - icon = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName) - while icon.attribute('visibleOnScreen') == 'false' - @meegoHome.Launcher.MPannableViewport( :name => 'SwipePage' ).MWidget( :name => 'glass' ).gesture(:Up, 1, 300) - sleep(0.2) - icon.refresh - end - xpos = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName).attribute('x') - ypos = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName).attribute('y') - @pos = "#{xpos}x#{ypos}" - - puts @pos - sleep (2) - system "#{PIXELCHANGED_BINARY} -c #{@pos} -f #{PIXELCHANGED_LOG} -q" - sleep (4) - system "pkill #{appName}" - else - #icon does not - #raise error and exit - raise "Application not found in Application grid" - exit 1 - end + if $path.include?("scratchbox") + puts "Inside SB, Do Nothing to unlock" + else + system "mcetool --set-tklock-mode=unlocked" + end + #restart duihome so that qttasserver notices it + #NOTE: Remove the cludge after duihome -> meegotouchhome renaming is complete + if not system("/sbin/initctl restart xsession/duihome") + system("/sbin/initctl restart xsession/mthome") end - def read_file(appName) - #Reading the log file to get the time - - lines = File.open(PIXELCHANGED_LOG).readlines().collect { |x| x.split(" ")[0].to_i } + system("initctl stop xsession/sysuid") + system("initctl stop xsession/applifed") + system("initctl stop xsession/search") + system("mv /usr/lib/qt4/plugins/testability/libtestability.so /tmp/.") +# system("pkill call-history") + sleep(4) + + end + + - # First line tells when the button is released - @start_time = lines[0] - puts "Line1: #{lines[0]}" - # Second one when the first pixel has changed its color - @end_time = lines[1] - puts "Line2: #{lines[1]}" - + # method called after any test case for cleanup purposes + def teardown + puts "exit from teardown" + system("initctl start xsession/sysuid") + system("initctl start xsession/applifed") + system("initctl start xsession/search") + system("mv /tmp/libtestability.so /usr/lib/qt4/plugins/testability/libtestability.so") + end + + def open_Apps(appName) + #Remove the Log file if it exists + if FileTest.exists?(PIXELCHANGED_LOG) + system "rm #{PIXELCHANGED_LOG}" end - - - def measure_time - #Measuring the Startup Time for applications - app_t = @end_time - @start_time - return app_t + sleep(2) + + if @options[:command] != nil + puts "#{GET_COORDINATES_SCRIPT} -g" + system "#{GET_COORDINATES_SCRIPT} -g" +# system "ls -l -s -R /usr/share/applications" + start_command ="`#{PIXELCHANGED_BINARY} -q >> #{PIXELCHANGED_LOG} &`; #{FALA_GETTIME_BINARY} \"Started from command line\" >> #{PIXELCHANGED_LOG}; #{@options[:command]} &" + puts "start command: #{start_command}" + system "#{start_command}" + sleep (4) + puts "pkill \"#{@options[:command]}\"" + system "pkill \"#{@options[:command]}\"" + + else + @pos = `#{GET_COORDINATES_SCRIPT} -a #{@options[:application]}` + + puts @pos + sleep (2) + system "#{PIXELCHANGED_BINARY} -c #{@pos} -f #{PIXELCHANGED_LOG} -q" + sleep (4) + system "pkill #{appName}" end - def test_performance - wL = [] - woL = [] - wLsum = 0 - woLsum = 0 - - #Run Application with invoker - for i in 1..COUNT - print "Now Launching #{APP_WITH_LAUNCHER} %d times\n" %i - open_Apps(APP_WITH_LAUNCHER) - sleep (5) - read_file(APP_WITH_LAUNCHER) - wL.push(measure_time) - end - - - #Run Application without invoker - for i in 1..COUNT - print "Now Launching #{APP_WITHOUT_LAUNCHER} %d times\n" %i - open_Apps(APP_WITHOUT_LAUNCHER) - sleep (5) - read_file(APP_WITHOUT_LAUNCHER) - woL.push(measure_time) - end - print "Startup time in milliseconds\n" - print "With Launcher \t\t Without Launcher\n" - - #Printing the data - for i in 0..COUNT-1 - print "%d \t\t\t %d\n" %[wL[i],woL[i]] - wLsum = wLsum + wL[i] - woLsum = woLsum + woL[i] - end - print "\nAverage Values \n" - print "%d \t\t\t %d\n\n" %[wLsum/COUNT, woLsum/COUNT] + end + + def read_file(appName) + #Reading the log file to get the time + + lines = File.open(PIXELCHANGED_LOG).readlines().collect { |x| x.split(" ")[0].to_i } + + # First line tells when the button is released + @start_time = lines[0] + puts "Clicked: #{lines[0]}" + # Second one when the first pixel has changed its color + @end_time = lines[1] + puts "Pixel changed: #{lines[1]}" + + end + + + def measure_time + #Measuring the Startup Time for applications + app_t = @end_time - @start_time + return app_t + end + + def test_performance + wL = [] + wLsum = 0 + + #Run Application with invoker + for i in 1..COUNT + print "Now Launching #{@options[:application]} %d times\n" %i + open_Apps(@options[:application]) + sleep (5) + read_file(@options[:application]) + wL.push(measure_time) + end + + + print "\n\nStartup time in milliseconds\n" + print "Application: #{@options[:application]} \n" + if @options[:limit] != nil + print "Time limit: #{@options[:limit]} \n" + end + + #Printing the data + for i in 0..COUNT-1 + print "%d \n" %[wL[i]] + wLsum = wLsum + wL[i] + end + print "\nAverage: \n" + print "%d\n" %[wLsum/COUNT] - + if @options[:limit] != nil + assert((wLsum/COUNT) < @options[:limit], "Application: #{@options[:application]} avarage startup was slower than #{@options[:limit]} ms") end + + end end diff --git a/tests/Harmattan/perftests/tests.xml b/tests/Harmattan/perftests/tests.xml index 6b0195c..3ddcad7 100644 --- a/tests/Harmattan/perftests/tests.xml +++ b/tests/Harmattan/perftests/tests.xml @@ -5,7 +5,7 @@ - + /usr/bin/waitloadavg.rb -l 1.0 -p 1.0 -t 120 @@ -24,13 +24,41 @@ - + /usr/bin/waitloadavg.rb -l 1.0 -p 1.0 -t 120 - - source /tmp/session_bus_address.user; DISPLAY=:0 /usr/share/applauncherd-testscripts/test-perf.rb name test_performance > /tmp/launcher_perf_new.txt + + source /tmp/session_bus_address.user; DISPLAY=:0 /usr/share/applauncherd-testscripts/test-perf.rb name test_performance -- -a fala_wl > /tmp/perf_grid_with_launcher.txt + + + + source /tmp/session_bus_address.user; DISPLAY=:0 /usr/share/applauncherd-testscripts/test-perf.rb name test_performance -- -a fala_wol > /tmp/perf_grid_without_launcher.txt + + + + false + true + + + + /tmp/perf_grid_with_launcher.txt + /tmp/perf_grid_without_launcher.txt + + + + + + + /usr/bin/waitloadavg.rb -l 1.0 -p 1.0 -t 120 + + + + source /tmp/session_bus_address.user; DISPLAY=:0 /usr/share/applauncherd-testscripts/test-perf.rb name test_performance -- -c /usr/bin/fala_wl > /tmp/perf_commandline_with_launcher.txt + + + source /tmp/session_bus_address.user; DISPLAY=:0 /usr/share/applauncherd-testscripts/test-perf.rb name test_performance -- -c /usr/bin/fala_wol > /tmp/perf_commandline_without_launcher.txt false @@ -38,7 +66,8 @@ - /tmp/launcher_perf_new.txt + /tmp/perf_commandline_with_launcher.txt + /tmp/perf_commandline_without_launcher.txt