diff options
author | Martin Wolf <ext-martin.2.wolf@nokia.com> | 2010-05-17 16:02:02 +0300 |
---|---|---|
committer | Martin Wolf <ext-martin.2.wolf@nokia.com> | 2010-05-17 16:02:02 +0300 |
commit | def2b0c7930cd92b08351844a2e40a8e3ed94dae (patch) | |
tree | eb7ecc6129ff639f93ef54bdb08e3f0a200854b3 /tests/test-performance/dbus-spammer | |
parent | 0e279e4350932643144f4ba9ac0afe501cb94c47 (diff) |
Added performance tests
Diffstat (limited to 'tests/test-performance/dbus-spammer')
-rw-r--r-- | tests/test-performance/dbus-spammer/dbus-services.cpp | 120 | ||||
-rw-r--r-- | tests/test-performance/dbus-spammer/dbus-services.h | 74 | ||||
-rw-r--r-- | tests/test-performance/dbus-spammer/dbus-spammer.cpp | 238 | ||||
-rw-r--r-- | tests/test-performance/dbus-spammer/dbus-spammer.pro | 21 |
4 files changed, 453 insertions, 0 deletions
diff --git a/tests/test-performance/dbus-spammer/dbus-services.cpp b/tests/test-performance/dbus-spammer/dbus-services.cpp new file mode 100644 index 0000000..d084ce0 --- /dev/null +++ b/tests/test-performance/dbus-spammer/dbus-services.cpp @@ -0,0 +1,120 @@ +#include "dbus-services.h" + +DbusSpammer::DbusSpammer(int id, QString service, int messageLen) : QThread() +{ + firstTime = true; +// qDebug("Hello world from DbusSpammer::DbusSpammer(%d, %s, %d)", id, qPrintable(service), messageLen); + + myBus = dbus_bus_get(DBUS_BUS_SESSION, NULL); + if( myBus == NULL ) + { + qDebug("Failed to access session bus!"); + return; + } + + threadID = id; + serviceName = service; + spamData.fill('A', messageLen); + pszSpamData = qPrintable(spamData); + + myMessage = dbus_message_new_method_call(qPrintable(service), "/", NULL, "ping"); + if( myMessage == NULL ) + { + qDebug("Failed to create dbus message! Out of memory?"); + return; + } + + dbus_message_append_args(myMessage, DBUS_TYPE_STRING, &pszSpamData, DBUS_TYPE_INVALID); + + timerID = startTimer(0); +} + +DbusSpammer::~DbusSpammer() +{ + killTimer(timerID); + + dbus_message_unref(myMessage); + dbus_connection_unref(myBus); +} + +void DbusSpammer::run() +{ +// sleep(1); +// printf("Thread #%d: Using service '%s' ...\n", threadID, qPrintable(serviceName)); + + exec(); +} + +void DbusSpammer::timerEvent(QTimerEvent*) +{ + killTimer(timerID); + + if( firstTime ) + { + dbus_connection_send(myBus, myMessage, NULL); + dbus_connection_flush(myBus); + } + else + { + DBusError error; + dbus_error_init(&error); + DBusMessage* reply = dbus_connection_send_with_reply_and_block(myBus, myMessage, 1000, &error); + + if( dbus_error_is_set(&error) ) + { + if( QString(error.name) != QString("org.freedesktop.DBus.Error.AccessDenied") ) + qDebug("Thread #%d dbus error %s:\n %s", threadID, error.name, error.message); + } + + if( reply ) + { + dbus_message_unref(reply); + } + } + + firstTime = false; + timerID = startTimer(0); +} + +DbusServer::DbusServer(int id) +{ + serviceID = id; + serviceName.sprintf("com.nokia.spam.dbus%d", id); +} + +DbusServer::~DbusServer() +{ + if( myBus ) + { + delete myBus; + myBus = NULL; + } +} + +void DbusServer::run() +{ + myBus = new QDBusConnection(QDBusConnection::sessionBus().sessionBus()); + if( !myBus || !myBus->isConnected() ) + { + qDebug("Connection error!"); + return; + } + + if( !myBus->registerService(serviceName) ) + { + qDebug("Service #%d: %s", serviceID, qPrintable(myBus->lastError().message())); + return; + } + + // Register all slots as dbus methods + myBus->registerObject("/", this, QDBusConnection::ExportScriptableSlots); + +// qDebug("DbusServer(%d) running!", serviceID); + exec(); +} + +QString DbusServer::ping(const QString &arg) +{ + // Just return back + return QString("%1").arg(arg); +} diff --git a/tests/test-performance/dbus-spammer/dbus-services.h b/tests/test-performance/dbus-spammer/dbus-services.h new file mode 100644 index 0000000..6924fdc --- /dev/null +++ b/tests/test-performance/dbus-spammer/dbus-services.h @@ -0,0 +1,74 @@ +#ifndef _DBUS_THREAD_ +#define _DBUS_THREAD_ + +#include <QList> +#include <QtDBus/QtDBus> +#include <QtCore/QObject> +#include <QtCore/QCoreApplication> +#include <dbus/dbus.h> + +typedef QList<QThread*> Threads; +typedef QList<QObject*> Servers; + +class Maintainer : public QObject +{ + Q_OBJECT + +public: + Maintainer(Threads* t); + ~Maintainer(); + +protected: + void timerEvent(QTimerEvent *e); + + int timerID; + Threads* threads; + bool allOnline; +}; + +class DbusSpammer : public QThread +{ +public: + DbusSpammer(int id, QString service, int messageLen); + ~DbusSpammer(); + + void run(); + + DBusConnection* myBus; + DBusMessage* myMessage; + + bool firstTime; + bool exitThread; + int threadID; + const char* pszSpamData; + QString spamData; + QString serviceName; + +protected: + void timerEvent(QTimerEvent *e); + + int timerID; +}; + +class DbusServer: public QThread +{ + Q_OBJECT + +public: + DbusServer(int id); + ~DbusServer(); + + const QString& getServiceName() { return serviceName; } + const int getServiceID() { return serviceID; } + void run(); + +private: + QDBusConnection* myBus; + QString serviceName; + int serviceID; + +public slots: + Q_SCRIPTABLE QString ping(const QString &arg); +}; + +#endif // _DBUS_THREAD_ diff --git a/tests/test-performance/dbus-spammer/dbus-spammer.cpp b/tests/test-performance/dbus-spammer/dbus-spammer.cpp new file mode 100644 index 0000000..2d84a60 --- /dev/null +++ b/tests/test-performance/dbus-spammer/dbus-spammer.cpp @@ -0,0 +1,238 @@ +#include <stdio.h> +#include <signal.h> +#include "dbus-services.h" + +sig_atomic_t volatile g_exit = 0; + +Maintainer::Maintainer(Threads* t) : QObject() +{ + allOnline = false; + threads = t; + timerID = startTimer(0); +} + +Maintainer::~Maintainer() +{ + killTimer(timerID); +} + +void Maintainer::timerEvent(QTimerEvent*) +{ + if( !allOnline ) + { + int count = 0; + Threads::iterator th; + for( th = threads->begin(); th != threads->end(); ++th ) + { + DbusSpammer* t = dynamic_cast<DbusSpammer*>(*th); + if( t ) + { + if( t->firstTime ) + count++; + } + } + + allOnline = (count == 0) && (threads->count() > 0); + + if( allOnline ) + printf("All thread online and working!\n"); + } + + fflush(stdout); + fflush(stderr); + + if( g_exit ) + QMetaObject::invokeMethod(QCoreApplication::instance(), "quit"); +} + +class CommandLineParser +{ +public: + CommandLineParser(int argc, char** argv) + { + threadCount = 10; + dataSize = 512; + + parseArguments(argc, argv); + } + +public: + int threadCount; + int dataSize; + +private: + void parseArguments(int argc, char** argv) + { + int option, tmp; + + while( (option = getopt(argc, argv, "ht:s:")) != -1 ) + { + switch( option ) + { + case 'h': + usage(0); + return; + case 't': + tmp = atoi(optarg); + if( tmp > 0 ) + { + threadCount = tmp; + printf("Thread count: %d\n", threadCount); + } + else + { + printf("Invalid thread count, using default value %d!\n", threadCount); + } + break; + case 's': + tmp = atoi(optarg); + if( tmp > 0 ) + { + dataSize = tmp; + printf("Data size: %d\n", dataSize); + } + else + { + printf("Invalid data size, using default value %d!\n", dataSize); + } + break; + default: + usage(-1); + return; + } + } + } + + void usage(int theExitCode) + { + printf("usage: dbus-spammer [-h] [-t thread_count] [-s data_size]\n"); + printf("default values:\n"); + printf(" thread_count: %d\n", threadCount); + printf(" data_size : %d\n", dataSize); + exit(theExitCode); + } +}; + +void signal_handler(int signo, siginfo_t *info, void *data) +{ + switch( signo ) + { + case SIGHUP: + case SIGTERM: + case SIGINT: + default: + puts("Caught exit signal!"); + g_exit = 1; + } + + (void)info; + (void)data; +} + +bool installSignals() +{ + struct sigaction sa; + + memset(&sa, 0, sizeof(struct sigaction)); + sa.sa_sigaction = signal_handler; + sa.sa_flags = SA_SIGINFO; + + if( sigaction(SIGHUP, &sa, NULL) < 0 || sigaction(SIGTERM, &sa, NULL) < 0 || sigaction(SIGINT, &sa, NULL) < 0 ) + { + puts("Failed to install signal handlers"); + return false; + } + + return true; +} + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + CommandLineParser cmd(argc, argv); + + int count = cmd.threadCount; + + Threads threads; + Servers servers; + + if( !installSignals() ) + { + return -2; + } + + if( !QDBusConnection::sessionBus().isConnected() ) + { + puts("Cannot connect to the D-Bus session bus."); + return -1; + } + + Maintainer maintainer(&threads); + + printf("Starting pair: "); + for( int i = 0; i < count; i++ ) + { + printf("#%d", i); + fflush(stdout); + DbusServer* s = new DbusServer(i); + s->start(QThread::NormalPriority); + servers.push_back(s); + usleep(100000); + + QThread* t = new DbusSpammer(i, s->getServiceName(), cmd.dataSize); + threads.push_back(t); + t->start(QThread::NormalPriority); + } + + puts(""); + + app.exec(); + + Threads::iterator th; + printf("Cleaning thread: "); + for( th = threads.begin(); th != threads.end(); ++th ) + { + DbusSpammer* t = dynamic_cast<DbusSpammer*>(*th); + if( t ) + { + printf("#%d", t->threadID); + + t->quit(); + int cnt = 0; + while( t->isRunning() ) + { + fflush(stdout); + fflush(stderr); + if( ++cnt == 1000 ) + { + printf("[T!]"); + t->terminate(); + break; + } + usleep(1000); + } + delete t; + } + } + puts(" ... done!"); + + Servers::iterator sv; + printf("Cleaning service: "); + for( sv = servers.begin(); sv != servers.end(); ++sv ) + { + DbusServer* s = dynamic_cast<DbusServer*>(*sv); + if( s ) + { + printf("#%d", s->getServiceID()); + s->quit(); + while( !s->isFinished() ) + usleep(1000); + + delete s; + } + } + + puts(" ... done!"); + + return 0; +} diff --git a/tests/test-performance/dbus-spammer/dbus-spammer.pro b/tests/test-performance/dbus-spammer/dbus-spammer.pro new file mode 100644 index 0000000..752d740 --- /dev/null +++ b/tests/test-performance/dbus-spammer/dbus-spammer.pro @@ -0,0 +1,21 @@ +TEMPLATE = app +TARGET = dbus-spammer +MOC_DIR = .moc +OBJECTS_DIR = .obj +DEPENDPATH += . +QT = core dbus +CONFIG += console link_pkgconfig +CONFIG -= app_bundle +PKGCONFIG += dbus-1 + +QMAKE_CXXFLAGS += -Wall + +# Input +SOURCES += dbus-spammer.cpp dbus-services.cpp +HEADERS += dbus-services.h + +QMAKE_DISTCLEAN += -r .moc .obj + +# Install options +target.path = /usr/lib/libresourceqt-performance-tests/ +INSTALLS = target |