mirror of https://github.com/cutefishos/appmotor
Remove mbooster
parent
a8ea5ce0ee
commit
593ea85036
@ -1,5 +0,0 @@
|
||||
# Tell qmake to use pkg-config to get correct compiler and linker
|
||||
# flags to make an application usable with applauncherd.
|
||||
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG += meegotouch-boostable
|
||||
@ -1,3 +0,0 @@
|
||||
Do not move meegotouch-boostable.pc unless you modify the CMakeLists.txt files of
|
||||
the test applications accordingly. Building the test applications looks for the
|
||||
.pc file in this directory to get correct linker flags.
|
||||
@ -1,5 +0,0 @@
|
||||
Name: meegotouch-boostable
|
||||
Description: make application boostable by applauncherd
|
||||
Version: 0.2.0
|
||||
Libs: -pie -rdynamic
|
||||
Cflags: -fPIC -fvisibility=hidden -fvisibility-inlines-hidden
|
||||
@ -1,149 +0,0 @@
|
||||
/*! \page libmeegotouchboost Using the MeeGo Touch booster
|
||||
|
||||
This section describes how to use the MeeGo Touch booster. The
|
||||
booster provides the application with the key libraries already
|
||||
present in the process, and instances of \c MApplication and
|
||||
\c MApplicationWindow waiting in the cache.
|
||||
|
||||
\section mtboostprereq Prerequisites
|
||||
|
||||
The launcher can start an application if the following prerequisites are met:
|
||||
|
||||
\li MApplication and MApplicationWindow instances are taken into use from
|
||||
MComponentCache
|
||||
|
||||
\li application is compiled and linked to a position-independent binary
|
||||
(executable or library)
|
||||
|
||||
\li application is started with the \c invoker command instead of executing the
|
||||
executable file
|
||||
|
||||
\section mtboostcompiling 1. Compiling and linking for launcher
|
||||
|
||||
If you intend to run a binary with \c applauncherd, compile it
|
||||
with \c -fPIC option to produce position independent code. It is
|
||||
recommended to link them either as shared libraries, or, preferably, as
|
||||
position-independent executables, which can be executed both traditionally and
|
||||
with the launcher. The \c -pie and \c -rdynamic linker flags
|
||||
accomplish this.
|
||||
|
||||
To improve linking and loading times of shared object libraries, it is
|
||||
recommended that you hide any unnecessary symbols from the resulting binary
|
||||
by using \c -fvisibility=hidden and \c -fvisibility-inlines-hidden
|
||||
flags as well. However, \c applauncherd needs to find the entry point
|
||||
for your application, so the symbol \c main needs to be explicitly made
|
||||
visible. This can be done as follows:
|
||||
|
||||
\code
|
||||
#include <MExport>
|
||||
|
||||
M_EXPORT int main(int argc, char **argv)
|
||||
{
|
||||
...
|
||||
}
|
||||
\endcode
|
||||
|
||||
If your application loads a plug-in that needs to access some symbols
|
||||
in the main application, the symbols also need to be exported. In
|
||||
addition, you must use the \c --global-syms invoker parameter, as
|
||||
described in \ref invokerparameters "Advanced invoker command line parameters".
|
||||
|
||||
Normally you do not need to worry about the compiler and linker
|
||||
flags, as the \c libmeegotouch-dev package provides configuration
|
||||
options for \c qmake, \c CMake, and \c pkg-config. If you are building
|
||||
a Debian package, make your package build-depend on \c
|
||||
libmeegotouch-dev and your application binary package depend on
|
||||
\c applauncherd.
|
||||
|
||||
For details on how to get the compiler and linker flags, see
|
||||
\ref usingqmake "Using qmake", \ref usingcmake "Using CMake", or
|
||||
\ref usingpkgconfig "Using pkg-config".
|
||||
|
||||
\section mtboostcache 2. Utilising the booster cache
|
||||
|
||||
Instantiating \c MApplication and \c MApplicationWindow is a relatively
|
||||
expensive operation. The MeeGo Touch booster helps reduce application startup
|
||||
latency by creating instances of the classes in \c MComponentCache.
|
||||
|
||||
MApplication instance must be taken from the MComponentCache. It is
|
||||
recommended to take MApplicationWindow from the cache as well. Thus,
|
||||
if the classes are instantiated in the application as follows:
|
||||
|
||||
\code
|
||||
MApplication application(argc, argv);
|
||||
MApplicationWindow window;
|
||||
\endcode
|
||||
|
||||
Modify the code as follows:
|
||||
|
||||
\code
|
||||
MApplication* application = MComponentCache::mApplication(argc, argv);
|
||||
MApplicationWindow* window = MComponentCache::mApplicationWindow();
|
||||
\endcode
|
||||
|
||||
The cache class works both with the booster and without it. In the
|
||||
non-boosted case there are no pre-created instances, so the cache
|
||||
class simply creates the instances on the fly.
|
||||
|
||||
The ownership of the instances is transferred from the cache to the
|
||||
application code. The instances need to be deleted in the correct
|
||||
order, deleting the \c MApplication instance before the \c
|
||||
MApplicationWindow instance is known to cause crashes.
|
||||
|
||||
\section mtboostexit 3. Adapting application source code
|
||||
|
||||
Making use of the cache is typically the only modification that you need to
|
||||
make in the application. However, if the application has explicit calls to \c
|
||||
exit(), change these to use \c _exit() instead. The brief
|
||||
explanation is that this prevents cleanup actions related to shared
|
||||
libraries to be performed multiple times. For more details, see
|
||||
\ref limitations "Limitations and known issues".
|
||||
|
||||
\section mtboostinvoker 4. Launching the application
|
||||
|
||||
Now everything should be in place for launching the application. The
|
||||
linker flags create a Position Independent Binary (PIE), so the
|
||||
application can still be invoked from the command line. In order to
|
||||
verify that the modifications done to the application and the build
|
||||
scripts have not broken anything, it is a good idea at this point to
|
||||
check that the application still starts and functions normally from
|
||||
the command line:
|
||||
|
||||
\code
|
||||
$ ./myApp
|
||||
\endcode
|
||||
|
||||
The next step is to use the \c invoker to launch the application. In
|
||||
order for this to work, you need to have \c applauncherd and \c
|
||||
booster-m (the MeeGo Touch booster process) running. To check that this is the
|
||||
case, you can do:
|
||||
|
||||
\code
|
||||
$ ps ax | grep booster-m
|
||||
\endcode
|
||||
|
||||
If you do not see the booster process, you need to start \c
|
||||
applauncherd manually. In MeeGo 1.2 Harmattan, \c applauncherd should
|
||||
be running as part of the UI session.
|
||||
|
||||
Once you have verified that the booster process is running, you can
|
||||
use the following command line to ask the booster process to turn into
|
||||
your application:
|
||||
|
||||
\code
|
||||
invoker --type=m /usr/bin/myApp
|
||||
\endcode
|
||||
|
||||
\section mtboostfinishingtouch 5. Finishing touches
|
||||
|
||||
The invoker can also provide single instance behaviour and a splash
|
||||
screen for your application as follows. For more details, see
|
||||
\ref singleinstance "Enabling single instance support for an application" and
|
||||
\ref splash "Enabling a splash screen for an application".
|
||||
|
||||
\code
|
||||
/usr/bin/invoker --single-instance --splash=/usr/share/myApp/splash.jpg --type=m /usr/bin/myApp
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
# Qt support
|
||||
include(${QT_USE_FILE})
|
||||
|
||||
set(LAUNCHER "${CMAKE_HOME_DIRECTORY}/src/launcherlib")
|
||||
set(COMMON "${CMAKE_HOME_DIRECTORY}/src/common")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${COMMON} ${LAUNCHER})
|
||||
|
||||
# Hide all symbols except the ones explicitly exported in the code (like main())
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
||||
|
||||
# Set sources
|
||||
set(SRC mbooster.cpp pluginfactory.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp
|
||||
${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp
|
||||
${LAUNCHER}/singleinstance.cpp ${LAUNCHER}/socketmanager.cpp
|
||||
${COMMON}/eventhandler.cpp)
|
||||
|
||||
set(MOC_HDRS ${COMMON}/eventhandler.h)
|
||||
qt4_wrap_cpp(MOC_SRC ${MOC_HDRS})
|
||||
|
||||
# Set libraries to be linked.
|
||||
link_libraries(${MEEGOTOUCH_LIBRARIES} ${LIBDL} ${QT_QTCORE_LIBRARY})
|
||||
|
||||
# Set executable
|
||||
add_library(mbooster MODULE ${SRC} ${MOC_SRC})
|
||||
|
||||
# Add install rule
|
||||
install(TARGETS mbooster DESTINATION /usr/lib/applauncherd/)
|
||||
@ -1,123 +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 "mbooster.h"
|
||||
#include "logger.h"
|
||||
#include "connection.h"
|
||||
|
||||
#ifdef HAVE_MCOMPONENTCACHE
|
||||
#include <mcomponentcache.h>
|
||||
#endif
|
||||
|
||||
const string MBooster::m_socketId = "/tmp/boostm";
|
||||
const string MBooster::m_temporaryProcessName = "booster-m";
|
||||
|
||||
const string & MBooster::socketId() const
|
||||
{
|
||||
return m_socketId;
|
||||
}
|
||||
|
||||
bool MBooster::preload()
|
||||
{
|
||||
#ifdef HAVE_MCOMPONENTCACHE
|
||||
// Populate the cache (instantiates an MApplicationWindow and
|
||||
// an MApplication)
|
||||
MComponentCache::populateForMApplication();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const string & MBooster::socketName()
|
||||
{
|
||||
return m_socketId;
|
||||
}
|
||||
|
||||
const string & MBooster::temporaryProcessName()
|
||||
{
|
||||
return m_temporaryProcessName;
|
||||
}
|
||||
|
||||
const string & MBooster::boosterTemporaryProcessName() const
|
||||
{
|
||||
return temporaryProcessName();
|
||||
}
|
||||
|
||||
char MBooster::type()
|
||||
{
|
||||
return 'm';
|
||||
}
|
||||
|
||||
bool MBooster::receiveDataFromInvoker(int socketFd)
|
||||
{
|
||||
// Use the default implementation if in boot mode
|
||||
// (it won't require QApplication running).
|
||||
|
||||
if (bootMode())
|
||||
{
|
||||
return Booster::receiveDataFromInvoker(socketFd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Setup the conversation channel with the invoker.
|
||||
setConnection(new Connection(socketFd));
|
||||
|
||||
EventHandler handler(this, EventHandler::MEventHandler);
|
||||
handler.runEventLoop();
|
||||
|
||||
if (!connection()->connected())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Receive application data from the invoker
|
||||
if(!connection()->receiveApplicationData(appData()))
|
||||
{
|
||||
connection()->close();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close the connection if exit status doesn't need
|
||||
// to be sent back to invoker
|
||||
if (!connection()->isReportAppExitStatusNeeded())
|
||||
{
|
||||
connection()->close();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void MBooster::preinit()
|
||||
{
|
||||
QString appName = QFileInfo(m_appData->argv()[0]).fileName();
|
||||
|
||||
QString appClass = appName.left(1).toUpper();
|
||||
if (appName.length() > 1)
|
||||
appClass += appName.right(appName.length() - 1);
|
||||
|
||||
// char* app_name = qstrdup(appName.toLatin1().data());
|
||||
// QApplication::setAppName(app_name);
|
||||
|
||||
// char* app_class = qstrdup(appClass.toLatin1().data());
|
||||
// QApplication::setAppClass(app_class);
|
||||
|
||||
// Set the magic attribute so that paths are reinitialized
|
||||
// QApplication::setAttribute(Qt::AA_LinuxReinitPathsFromArgv0, true);
|
||||
}
|
||||
@ -1,117 +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 MBOOSTER_H
|
||||
#define MBOOSTER_H
|
||||
|
||||
#include <QApplication>
|
||||
#include "QFileInfo"
|
||||
|
||||
#include "eventhandler.h"
|
||||
#include "booster.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
/*!
|
||||
\class MBooster
|
||||
\brief MeeGo Touch -specific version of the Booster.
|
||||
|
||||
MBooster effectively fills MComponentCache with fresh objects.
|
||||
MeeGo Touch applications can then try to use already initialized objects
|
||||
from MComponentCache. This can significantly reduce the startup time of a
|
||||
MeeGo Touch application.
|
||||
*/
|
||||
class MBooster : public Booster
|
||||
{
|
||||
public:
|
||||
|
||||
//! \brief Constructor
|
||||
MBooster() {}
|
||||
|
||||
//! \brief Destructor
|
||||
virtual ~MBooster() {}
|
||||
|
||||
/*!
|
||||
* \brief Return the socket name common to all MBooster objects.
|
||||
* \return Path to the socket file.
|
||||
*/
|
||||
static const string & socketName();
|
||||
|
||||
//! Return the process name to be used when booster is not
|
||||
//! yet transformed into a running application
|
||||
static const string & temporaryProcessName();
|
||||
|
||||
//! \reimp
|
||||
virtual const string & boosterTemporaryProcessName() const;
|
||||
|
||||
//! \reimp
|
||||
virtual char boosterType() const { return type(); }
|
||||
|
||||
/*!
|
||||
* \brief Return a unique character ('m') represtenting the type of MBoosters.
|
||||
* \return Type character.
|
||||
*/
|
||||
static char type();
|
||||
|
||||
//! \reimp
|
||||
virtual const string & socketId() const;
|
||||
|
||||
protected:
|
||||
|
||||
//! \reimp
|
||||
virtual bool preload();
|
||||
|
||||
//! \reimp
|
||||
virtual bool receiveDataFromInvoker(int socketFd);
|
||||
|
||||
//! \reimp
|
||||
virtual void preinit();
|
||||
|
||||
private:
|
||||
|
||||
//! Disable copy-constructor
|
||||
MBooster(const MBooster & r);
|
||||
|
||||
//! Disable assignment operator
|
||||
MBooster & operator= (const MBooster & r);
|
||||
|
||||
static const string m_socketId;
|
||||
|
||||
//! Process name to be used when booster is not
|
||||
//! yet transformed into a running application
|
||||
static const string m_temporaryProcessName;
|
||||
|
||||
//! wait for socket connection
|
||||
void accept();
|
||||
|
||||
private slots:
|
||||
|
||||
//! Qt signal handler for SIGHUP.
|
||||
void handleSigHup();
|
||||
|
||||
//! Qt signal handler for theme change
|
||||
void notifyThemeChange();
|
||||
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
friend class Ut_MBooster;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // MBOOSTER_H
|
||||
@ -1,45 +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 <QtCore>
|
||||
#include "mbooster.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// Create a new plugin instance.
|
||||
Q_DECL_EXPORT void * create()
|
||||
{
|
||||
return new MBooster;
|
||||
}
|
||||
|
||||
Q_DECL_EXPORT char type()
|
||||
{
|
||||
return MBooster::type();
|
||||
}
|
||||
|
||||
Q_DECL_EXPORT const char * socketName()
|
||||
{
|
||||
return MBooster::socketName().c_str();
|
||||
}
|
||||
|
||||
Q_DECL_EXPORT const char * temporaryProcessName()
|
||||
{
|
||||
return MBooster::temporaryProcessName().c_str();
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
set(LAUNCHER ${CMAKE_HOME_DIRECTORY}/src/launcherlib)
|
||||
set(MBOOSTER ${CMAKE_HOME_DIRECTORY}/src/mbooster)
|
||||
set(COMMON "${CMAKE_HOME_DIRECTORY}/src/common")
|
||||
|
||||
# Set sources
|
||||
set(SRC ut_mbooster.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp
|
||||
${LAUNCHER}/connection.cpp
|
||||
${LAUNCHER}/logger.cpp
|
||||
${MBOOSTER}/mbooster.cpp ${COMMON}/eventhandler.cpp
|
||||
${LAUNCHER}/singleinstance.cpp ${LAUNCHER}/socketmanager.cpp)
|
||||
|
||||
# Set moc headers
|
||||
set(MOC_HDRS ut_mbooster.h ${COMMON}/eventhandler.h)
|
||||
|
||||
# Run moc
|
||||
qt4_wrap_cpp(MOC_SRC ${MOC_HDRS})
|
||||
|
||||
# Enable test library
|
||||
set(QT_USE_QTTEST TRUE)
|
||||
|
||||
# Set include paths
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/src/common ${LAUNCHER} ${MBOOSTER})
|
||||
|
||||
link_libraries(${QT_QTCORE_LIBRARY} ${QT_QTTEST_LIBRARY} ${MEEGOTOUCH_LIBRARIES} -ldl -lX11)
|
||||
|
||||
# Enable Qt (may not be needed, because already defined on higher level)
|
||||
include(${QT_USE_FILE})
|
||||
|
||||
add_executable(ut_mbooster ${SRC} ${MOC_SRC} )
|
||||
|
||||
# Install
|
||||
install(PROGRAMS ut_mbooster DESTINATION /usr/share/applauncherd-tests/)
|
||||
|
||||
@ -1,80 +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 "ut_mbooster.h"
|
||||
#include "mbooster.h"
|
||||
|
||||
#ifdef HAVE_MCOMPONENTCACHE
|
||||
#include <MComponentCache>
|
||||
#endif
|
||||
|
||||
Ut_MBooster::Ut_MBooster() :
|
||||
m_subject(new MBooster)
|
||||
{}
|
||||
|
||||
Ut_MBooster::~Ut_MBooster()
|
||||
{}
|
||||
|
||||
void Ut_MBooster::initTestCase()
|
||||
{}
|
||||
|
||||
void Ut_MBooster::cleanupTestCase()
|
||||
{}
|
||||
|
||||
void Ut_MBooster::testSocketName()
|
||||
{
|
||||
QVERIFY(MBooster::socketName() == MBooster::m_socketId);
|
||||
QVERIFY(m_subject->socketId() == MBooster::m_socketId);
|
||||
}
|
||||
|
||||
void Ut_MBooster::testType()
|
||||
{
|
||||
QVERIFY(MBooster::type() == 'm');
|
||||
QVERIFY(m_subject->boosterType() == 'm');
|
||||
}
|
||||
|
||||
void Ut_MBooster::testPreload()
|
||||
{
|
||||
#ifdef HAVE_MCOMPONENTCACHE
|
||||
|
||||
m_subject->preload();
|
||||
|
||||
const char * argv[] = {"foo"};
|
||||
int argc = 1;
|
||||
|
||||
QVERIFY(MComponentCache::mApplication(argc, const_cast<char **>(argv)));
|
||||
QVERIFY(MComponentCache::mApplicationWindow());
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void Ut_MBooster::testTemporaryProcessName()
|
||||
{
|
||||
QVERIFY(MBooster::temporaryProcessName() == MBooster::m_temporaryProcessName);
|
||||
QVERIFY(m_subject->temporaryProcessName() == MBooster::m_temporaryProcessName);
|
||||
QVERIFY(m_subject->boosterTemporaryProcessName() == MBooster::m_temporaryProcessName);
|
||||
}
|
||||
|
||||
void Ut_MBooster::testReceiveDataFromInvokerWithBadSocket()
|
||||
{
|
||||
QVERIFY(m_subject->receiveDataFromInvoker(-100) == false);
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(Ut_MBooster);
|
||||
|
||||
@ -1,53 +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 UT_MBOOSTER_H
|
||||
#define UT_MBOOSTER_H
|
||||
|
||||
#include<QtTest/QtTest>
|
||||
#include<QObject>
|
||||
|
||||
#include <tr1/memory>
|
||||
|
||||
#define UNIT_TEST
|
||||
|
||||
class MBooster;
|
||||
|
||||
class Ut_MBooster : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Ut_MBooster();
|
||||
virtual ~Ut_MBooster();
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void testSocketName();
|
||||
void testType();
|
||||
void testPreload();
|
||||
void testTemporaryProcessName();
|
||||
void testReceiveDataFromInvokerWithBadSocket();
|
||||
|
||||
private:
|
||||
std::tr1::shared_ptr<MBooster> m_subject;
|
||||
};
|
||||
|
||||
#endif // UT_MBOOSTER_H
|
||||
@ -1,267 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
This program tests the startup time of the given application with and
|
||||
without launcher.
|
||||
|
||||
Requirements:
|
||||
1. DISPLAY environment variable must be set correctly.
|
||||
2. DBus session bus must be running.
|
||||
3. DBus session bus address must be stored in /tmp/session_bus_address.user.
|
||||
4. Given application supports launcher with -launcher commandline argument.
|
||||
5. waitforwindow application should be installed.
|
||||
|
||||
Usage: test-perf-mbooster <launcherable application>
|
||||
|
||||
Example: test-perf-mbooster /usr/bin/testapp
|
||||
|
||||
Authors: Nimika Keshri nimika.1.keshri@nokia.com
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
import commands
|
||||
import time
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
TESTAPP = '/usr/bin/fala_testapp'
|
||||
LOG_FILE = '/tmp/testapp.log'
|
||||
DEV_NULL = file("/dev/null","w")
|
||||
|
||||
_start_time = 0
|
||||
_end_time = 0
|
||||
|
||||
def debug(*msg):
|
||||
sys.stderr.write('[DEBUG %s] %s\n' % (time.time(), ' '.join([str(s) for s in msg]),))
|
||||
|
||||
def error(*msg):
|
||||
sys.stderr.write('ERROR %s\n' % (' '.join([str(s) for s in msg]),))
|
||||
sys.exit(1)
|
||||
|
||||
def basename(filepath):
|
||||
"""
|
||||
return base name of a file
|
||||
"""
|
||||
return os.path.basename(filepath)
|
||||
def is_executable_file(filename):
|
||||
return os.path.isfile(filename) and os.access(filename, os.X_OK)
|
||||
|
||||
def check_prerequisites():
|
||||
if os.getenv('DISPLAY') == None:
|
||||
error("DISPLAY is not set. Check the requirements.")
|
||||
|
||||
if os.getenv('DBUS_SESSION_BUS_ADDRESS') == None:
|
||||
error("DBUS_SESSION_BUS_ADDRESS is not set.\n" +
|
||||
"You probably want to source /tmp/session_bus_address.user")
|
||||
|
||||
if not is_executable_file(TESTAPP):
|
||||
error("'%s' is not an executable file\n" % (TESTAPP,) +
|
||||
"(should be an application that supports launcher)")
|
||||
|
||||
|
||||
class launcher_perf_tests (unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
print "Setup Executed"
|
||||
|
||||
def tearDown(self):
|
||||
print "Teardown Executed"
|
||||
|
||||
#Other functions
|
||||
def start_timer(self):
|
||||
global _start_time
|
||||
_start_time = time.time()
|
||||
|
||||
def run_without_launcher(self, appname):
|
||||
"""starts the testapp without the launcher"""
|
||||
os.system ('mcetool --set-tklock-mode=unlocked')
|
||||
if os.path.exists(LOG_FILE) and os.path.isfile(LOG_FILE):
|
||||
os.system('rm %s' %LOG_FILE)
|
||||
self.start_timer()
|
||||
p = subprocess.Popen(appname,
|
||||
shell=False,
|
||||
stdout=DEV_NULL, stderr=DEV_NULL)
|
||||
debug("app", TESTAPP, "started without launcher")
|
||||
time.sleep(5)
|
||||
self.read_log()
|
||||
app_time = self.app_start_time()
|
||||
self.kill_process(appname)
|
||||
return app_time
|
||||
|
||||
def run_without_launcher_without_duihome(self, appname):
|
||||
"""starts the testapp without launcher and without duihome"""
|
||||
os.system ('mcetool --set-tklock-mode=unlocked')
|
||||
if os.path.exists(LOG_FILE) and os.path.isfile(LOG_FILE):
|
||||
os.system('rm %s' %LOG_FILE)
|
||||
os.system('pkill -STOP duihome')
|
||||
os.system('pkill -STOP meegotouchhome')
|
||||
self.start_timer()
|
||||
p = subprocess.Popen(TESTAPP,
|
||||
shell=False,
|
||||
stdout=DEV_NULL, stderr=DEV_NULL)
|
||||
debug("app", TESTAPP, "started without launcher")
|
||||
time.sleep(5)
|
||||
os.system('pkill -CONT duihome')
|
||||
os.system('pkill -CONT meegotouchhome')
|
||||
self.read_log()
|
||||
app_time = self.app_start_time()
|
||||
self.kill_process(appname)
|
||||
return app_time
|
||||
|
||||
def run_with_launcher(self, appname):
|
||||
"""starts the testapp with launcher and with duihome"""
|
||||
os.system ('mcetool --set-tklock-mode=unlocked')
|
||||
if os.path.exists(LOG_FILE) and os.path.isfile(LOG_FILE):
|
||||
os.system('rm %s' %LOG_FILE)
|
||||
|
||||
self.start_timer()
|
||||
os.system('invoker --type=m --no-wait %s' %TESTAPP)
|
||||
debug("app", TESTAPP, "started with launcher")
|
||||
time.sleep(5)
|
||||
self.read_log()
|
||||
app_time = self.app_start_time()
|
||||
self.kill_process(appname)
|
||||
return app_time
|
||||
|
||||
def run_with_launcher_without_duihome(self, appname):
|
||||
"""starts the testapp with launcher but without duihome"""
|
||||
os.system ('mcetool --set-tklock-mode=unlocked')
|
||||
if os.path.exists(LOG_FILE) and os.path.isfile(LOG_FILE):
|
||||
os.system('rm %s' %LOG_FILE)
|
||||
os.system('pkill -STOP duihome')
|
||||
os.system('pkill -STOP meegotouchhome')
|
||||
self.start_timer()
|
||||
os.system('invoker --type=m --no-wait %s' %TESTAPP)
|
||||
debug("app", TESTAPP, "started with launcher")
|
||||
time.sleep(5)
|
||||
os.system('pkill -CONT duihome')
|
||||
os.system('pkill -CONT meegotouchhome')
|
||||
self.read_log()
|
||||
app_time = self.app_start_time()
|
||||
self.kill_process(appname)
|
||||
return app_time
|
||||
|
||||
def read_log(self):
|
||||
"""Reads the log file to get the startup time"""
|
||||
global _end_time
|
||||
fh = open(LOG_FILE, "r")
|
||||
lines = fh.readlines()
|
||||
lastline = lines[len(lines)-2]
|
||||
_end_time = lastline.split()[0]
|
||||
return _end_time
|
||||
|
||||
def app_start_time(self):
|
||||
"""Calculates the startup time for the testapp"""
|
||||
global _app_start_time
|
||||
_app_start_time = float(_end_time) - float(_start_time)
|
||||
return _app_start_time
|
||||
|
||||
def kill_process(self, appname):
|
||||
"""Kills the testapp"""
|
||||
commands.getoutput("pkill -9 %s" % (basename(appname)[:15],))
|
||||
|
||||
|
||||
def perftest_with_launcher(self, appname):
|
||||
debug("run app with launcher without duihome")
|
||||
with_l_no_d = self.run_with_launcher_without_duihome(appname)
|
||||
time.sleep(5)
|
||||
|
||||
debug("run app with launcher with duihome")
|
||||
with_l_with_d = self.run_with_launcher(appname)
|
||||
time.sleep(5)
|
||||
|
||||
return with_l_with_d, with_l_no_d
|
||||
|
||||
def perftest_without_launcher(self, appname):
|
||||
"""Runs all the 4 scenarios with and without launcher"""
|
||||
debug("run app without launcher with duihome")
|
||||
no_l_with_d = self.run_without_launcher(appname)
|
||||
time.sleep(5)
|
||||
|
||||
debug("run app without launcher without duihome")
|
||||
no_l_no_d = self.run_without_launcher_without_duihome(appname)
|
||||
time.sleep(5)
|
||||
|
||||
return no_l_with_d, no_l_no_d
|
||||
|
||||
|
||||
def print_test_report(self, with_without_times, fileobj):
|
||||
"""
|
||||
with_without_times is a list of pairs:
|
||||
(with_launcher_startup_time,
|
||||
without_launcher_startup_time)
|
||||
"""
|
||||
def writeline(*msg):
|
||||
fileobj.write("%s\n" % ' '.join([str(s) for s in msg]))
|
||||
def fmtfloat(f):
|
||||
return "%.2f" % (f,)
|
||||
def filterstats(data, field):
|
||||
return tuple([d[field] for d in data])
|
||||
|
||||
if with_without_times == []: return
|
||||
|
||||
writeline("")
|
||||
rowformat = "%12s %12s %12s %12s"
|
||||
writeline('Startup times [s]:')
|
||||
|
||||
writeline(rowformat % ('launcher-Yes', 'launcher-Yes', 'launcher-No', 'launcher-No'))
|
||||
writeline(rowformat % ('duihome-Yes', 'duihome-No', 'duihome-Yes', 'duihome-No'))
|
||||
|
||||
t1,t2,t3,t4 = [], [], [], []
|
||||
for no_l_with_d, no_l_no_d, with_l_with_d, with_l_no_d in with_without_times:
|
||||
t1.append(no_l_with_d)
|
||||
t2.append(no_l_no_d)
|
||||
t3.append(with_l_with_d)
|
||||
t4.append(with_l_no_d)
|
||||
writeline(rowformat % (fmtfloat(no_l_with_d), fmtfloat(no_l_no_d),
|
||||
fmtfloat(with_l_with_d), fmtfloat(with_l_no_d)))
|
||||
|
||||
writeline('Average times:')
|
||||
writeline(rowformat % (fmtfloat(sum(t1)/len(t1)), fmtfloat(sum(t2)/len(t2)),
|
||||
fmtfloat(sum(t3)/len(t3)), fmtfloat(sum(t4)/len(t4))))
|
||||
return fmtfloat(sum(t1)/len(t1))
|
||||
|
||||
def test_001(self):
|
||||
"""Performance test to measure the startup time for application
|
||||
launched using launcher and comparing the results with application launched
|
||||
without launcher"""
|
||||
|
||||
times = []
|
||||
|
||||
times1, times2 = [], []
|
||||
|
||||
for i in xrange(3):
|
||||
times1.append(self.perftest_with_launcher(TESTAPP))
|
||||
|
||||
for i in xrange(3):
|
||||
times2.append(self.perftest_without_launcher(TESTAPP))
|
||||
|
||||
times = [[t1[0], t1[1], times2[i][0], times2[i][1]] for i, t1 in enumerate(times1)]
|
||||
avg_with_launcher = self.print_test_report(times, sys.stdout)
|
||||
self.assert_(float(avg_with_launcher) < float(0.75), "application launched with launcher takes more than 0.75 sec")
|
||||
|
||||
|
||||
# main
|
||||
if __name__ == '__main__':
|
||||
check_prerequisites()
|
||||
tests = sys.argv[1:]
|
||||
mysuite = unittest.TestSuite(map(launcher_perf_tests, tests))
|
||||
result = unittest.TextTestRunner(verbosity=2).run(mysuite)
|
||||
if not result.wasSuccessful():
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
Loading…
Reference in New Issue