diff options
Diffstat (limited to 'tests/test-performance/test-resourceqt-performance')
4 files changed, 695 insertions, 0 deletions
diff --git a/tests/test-performance/test-resourceqt-performance/client.cpp b/tests/test-performance/test-resourceqt-performance/client.cpp new file mode 100644 index 0000000..e172d21 --- /dev/null +++ b/tests/test-performance/test-resourceqt-performance/client.cpp @@ -0,0 +1,380 @@ +#include <QtCore/QCoreApplication> +#include <QtCore/QFile> + +#include <sys/time.h> +#include <sys/types.h> +#include <sys/select.h> + +#include "client.h" + +using namespace ResourcePolicy; + +Client::Client(int testCnt, QString appClass, uint32_t all, uint32_t optional) : QObject() +{ + QSettings settings("/usr/lib/libresourceqt-performance-tests/test-resourceqt-performance.ini", QSettings::IniFormat); + + settings.beginGroup("main"); + reportAcquire = settings.value("acqreport", "/tmp/acquire.csv").toString(); + reportRelease = settings.value("relreport", "/tmp/release.csv").toString(); + settings.endGroup(); + + totalTestCount = testCnt; + applicationClass = appClass; + resourceSet = NULL; + testState = TestStart; + testCounter = 1; + + allResources = all; + optionalResources = optional; + firstTime = true; + + failed = 0; + + mainTimerID = startTimer(0); +} + +Client::~Client() +{ + killTimer(mainTimerID); + + if( resourceSet != NULL ) + { + delete resourceSet; + resourceSet = NULL; + } +} + +uint32_t Client::parseResourceList(QString resourceListStr) +{ + struct + { + uint32_t resourceType; + const char* resourceName; + } + resourceDef[] = + { + { RES_AUDIO_PLAYBACK, "AudioPlayback" }, + { RES_VIDEO_PLAYBACK, "VideoPlayback" }, + { RES_AUDIO_RECORDING, "AudioRecording" }, + { RES_VIDEO_RECORDING, "VideoRecording" }, + { RES_VIBRA, "Vibra" }, + { RES_LEDS, "Leds" }, + { RES_BACKLIGHT, "BackLight" }, + { RES_SYSTEM_BUTTON, "SystemButton" }, + { RES_LOCK_BUTTON, "LockButton" }, + { RES_SCALE_BUTTON, "ScaleButton" }, + { RES_SNAP_BUTTON, "SnapButton" }, + { RES_LENS_COVER, "LensCover" }, + { 0, NULL } + }; + + uint32_t resourceList = 0; + + if( resourceListStr.isEmpty() || resourceListStr.isNull() ) + { + return 0; + } + else + { + QStringList resList = resourceListStr.split(",", QString::SkipEmptyParts); + + for( int i = 0; i < resList.count(); i++ ) + { + int pos = 0; + while( resourceDef[pos].resourceName != NULL ) + { + if( resList[i] == resourceDef[pos].resourceName ) + break; + + pos++; + } + + if( !resourceDef[pos].resourceName ) + { + const char* res = qPrintable(resList[i]); + printf("Ignoring invalid resource name '%s'\n", res); + } + else + { + resourceList |= resourceDef[pos].resourceType; + } + } + } + + return resourceList; +} + +void Client::createSet(uint32_t list, uint32_t optional) +{ + uint32_t resources[] = + { + RES_AUDIO_PLAYBACK, RES_VIDEO_PLAYBACK, RES_AUDIO_RECORDING, RES_VIDEO_RECORDING, RES_VIBRA, RES_LEDS, RES_BACKLIGHT, RES_SYSTEM_BUTTON, + RES_LOCK_BUTTON, RES_SCALE_BUTTON, RES_SNAP_BUTTON, RES_LENS_COVER, 0 + }; + + int pos = 0; + while( resources[pos] ) + { + if( list & resources[pos] ) + { + Resource* resource = NULL; + ResourceType res = getResourceType(resources[pos]); + bool opt = (optional & resources[pos]) == resources[pos]; + + resource = allocateResource(res, opt); + if( resource ) + { + resourceSet->addResourceObject(resource); + } + } + + pos++; + } +} + +bool Client::initialize() +{ + if( resourceSet ) + { + return false; + } + + resourceSet = new ResourceSet(applicationClass); + if( resourceSet == NULL ) + { + return false; + } + resourceSet->setAlwaysReply(); + + createSet(allResources, optionalResources); + + if( !connect(resourceSet, SIGNAL(resourcesGranted(QList<ResourcePolicy::ResourceType> )), this, SLOT(resourceAcquiredHandler(QList<ResourcePolicy::ResourceType>))) ) + { + return false; + } + + if( !connect(resourceSet, SIGNAL(resourcesDenied()), this, SLOT(resourceDeniedHandler())) ) + { + return false; + } + + if( !connect(resourceSet, SIGNAL(lostResources()), this, SLOT(resourceLostHandler())) ) + { + return false; + } + + connect(resourceSet, SIGNAL(resourcesReleased()), this, SLOT(resourceReleasedHandler())); + + return true; +} + +bool Client::cleanup() +{ + if( !disconnect(resourceSet, SIGNAL(resourcesGranted(QList<ResourcePolicy::ResourceType> )), this, SLOT(resourceAcquiredHandler(QList<ResourcePolicy::ResourceType>))) ) + { + return false; + } + + if( !disconnect(resourceSet, SIGNAL(resourcesDenied()), this, SLOT(resourceDeniedHandler())) ) + { + return false; + } + + if( !disconnect(resourceSet, SIGNAL(lostResources()), this, SLOT(resourceLostHandler())) ) + { + return false; + } + + disconnect(resourceSet, SIGNAL(resourcesReleased()), this, SLOT(resourceReleasedHandler())); + + if( resourceSet != NULL ) + { + delete resourceSet; + resourceSet = NULL; + } + + return true; +} + +Resource* Client::allocateResource(ResourceType resource, bool optional) +{ + Resource* retValue = NULL; + + switch( resource ) + { + case AudioPlaybackType: + retValue = new AudioResource(); + break; + case VideoPlaybackType: + retValue = new VideoResource(); + break; + case AudioRecorderType: + retValue = new AudioRecorderResource(); + break; + case VideoRecorderType: + retValue = new VideoRecorderResource(); + break; + case VibraType: + retValue = new VibraResource(); + break; + case LedsType: + retValue = new LedsResource(); + break; + case BacklightType: + retValue = new BacklightResource(); + break; + case SystemButtonType: + retValue = new SystemButtonResource(); + break; + case LockButtonType: + retValue = new LockButtonResource(); + break; + case ScaleButtonType: + retValue = new ScaleButtonResource(); + break; + case SnapButtonType: + retValue = new SnapButtonResource(); + break; + case LensCoverType: + retValue = new LensCoverResource(); + break; + case NumberOfTypes: + return NULL; + } + + if( retValue ) + { + retValue->setOptional(optional); + } + else + { + printf("Unknown resource type - %d\n", resource); + } + + return retValue; +} + +ResourceType Client::getResourceType(uint32_t resource) +{ + switch( resource ) + { + case RES_AUDIO_PLAYBACK: + return AudioPlaybackType; + case RES_VIDEO_PLAYBACK: + return VideoPlaybackType; + case RES_AUDIO_RECORDING: + return AudioRecorderType; + case RES_VIDEO_RECORDING: + return VideoRecorderType; + case RES_VIBRA: + return VibraType; + case RES_LEDS: + return LedsType; + case RES_BACKLIGHT: + return BacklightType; + case RES_SYSTEM_BUTTON: + return SystemButtonType; + case RES_LOCK_BUTTON: + return LockButtonType; + case RES_SCALE_BUTTON: + return ScaleButtonType; + case RES_SNAP_BUTTON: + return SnapButtonType; + case RES_LENS_COVER: + return LensCoverType; + } + + return NumberOfTypes; +} + +void Client::resourceAcquiredHandler(const QList<ResourceType>& /*grantedResList*/) +{ + timeStatAcq.markEnd(false); + testState = TestRelease; +} + +void Client::resourceDeniedHandler() +{ +/* if( timeStat.markEnd() ) + { + timeStat.report(); + }*/ +} + +void Client::resourceLostHandler() +{ +/* if( timeStat.markEnd() ) + { + timeStat.report(); + }*/ +} + +void Client::resourceReleasedHandler() +{ + timeStatRel.markEnd(false); + testState = TestFinished; +} + +void Client::timerEvent(QTimerEvent*) +{ + if( firstTime ) + { + firstTime = false; + timeStatTotal.markStart(); + initialize(); + } + + switch( testState ) + { + case TestFinished: + if( testCounter == totalTestCount ) + { + cleanup(); + timeStatTotal.markEnd(false); + puts("\n*** RESULTS ***"); + printf("Total failed: %d/%d\n", failed, totalTestCount); + printf("Total time : %.2f ms\n", timeStatTotal.caseTime); + printf("Average time: %.2f ms (%.2f ms)\n", timeStatTotal.caseTime / (double)totalTestCount, timeStatTotal.caseTime / (double)(totalTestCount*2)); + printf("Acquire:\n\tAverage: %.2f ms\n\tMin : %.2f ms\n\tMax : %.2f ms\n", timeStatAcq.totalTime / (double)timeStatAcq.caseCount, timeStatAcq.totalMin, timeStatAcq.totalMax); + printf("Release:\n\tAverage: %.2f ms\n\tMin : %.2f ms\n\tMax : %.2f ms\n", timeStatRel.totalTime / (double)timeStatRel.caseCount, timeStatRel.totalMin, timeStatRel.totalMax); + timeStatAcq.exportData(qPrintable(reportAcquire)); + timeStatRel.exportData(qPrintable(reportRelease)); + QMetaObject::invokeMethod(QCoreApplication::instance(), "quit"); + } + else + { + testCounter++; + testState = TestStart; + } + break; + case TestWaiting: + break; + case TestStart: + testState = TestAcquire; + printf("\rRunning round %d of %d ... ", testCounter, totalTestCount); + fflush(stdout); + break; + case TestAcquire: + timeStatAcq.markStart(); + if( !resourceSet || !resourceSet->acquire() ) + { + timeStatAcq.markEnd(true); + testState = TestFinished; + failed++; + } + else + testState = TestWaiting; + break; + case TestRelease: + timeStatRel.markStart(); + if( !resourceSet || !resourceSet->release() ) + { + timeStatRel.markEnd(true); + testState = TestFinished; + failed++; + } + else + testState = TestWaiting; + break; + } +} diff --git a/tests/test-performance/test-resourceqt-performance/client.h b/tests/test-performance/test-resourceqt-performance/client.h new file mode 100644 index 0000000..c7ecb30 --- /dev/null +++ b/tests/test-performance/test-resourceqt-performance/client.h @@ -0,0 +1,175 @@ +#ifndef _CLIENT_H_ +#define _CLIENT_H_ + +#include <QList> +#include <QObject> + +#include <policy/resource-set.h> +#include <sys/time.h> + +#define RES_AUDIO_PLAYBACK (1<<0) +#define RES_VIDEO_PLAYBACK (1<<1) +#define RES_AUDIO_RECORDING (1<<2) +#define RES_VIDEO_RECORDING (1<<3) +#define RES_VIBRA (1<<4) +#define RES_LEDS (1<<5) +#define RES_BACKLIGHT (1<<6) +#define RES_SYSTEM_BUTTON (1<<7) +#define RES_LOCK_BUTTON (1<<8) +#define RES_SCALE_BUTTON (1<<9) +#define RES_SNAP_BUTTON (1<<10) +#define RES_LENS_COVER (1<<11) + +class TimeStat +{ +public: + double totalTime; + double caseTime; + double totalMax; + double totalMin; + int caseCount; + + TimeStat() + { + running = false; + totalTime = 0; + caseTime = 0; + caseCount = 0; + totalMax = 0; + totalMin = 9999999999.; + }; + + inline void markStart() + { + if( running ) + return; + + running = true; + gettimeofday(&start, NULL); + } + + inline void markEnd(bool failed) + { + if( !running ) + return; + + gettimeofday(&end, NULL); + + running = false; + + timevalSub(&end, &start, &end); + caseTime = end.tv_sec * 1000.0 + end.tv_usec / 1000.0; + + if( !failed ) + { + totalMax = (totalMax < caseTime) ? caseTime : totalMax; + totalMin = (totalMin > caseTime) ? caseTime : totalMin; + totalTime += caseTime; + data.push_back(caseTime); + caseCount++; + } + } + + void exportData(const char* name) + { + FILE* f = fopen(name, "wt"); + + fprintf(f, "Cnt;%d\n", caseCount); + fprintf(f, "Tot;%.4f\n", totalTime); + fprintf(f, "Max;%.4f\n", totalMax); + fprintf(f, "Min;%.4f\n", totalMin); + fprintf(f, "Avg;%.4f\n", totalTime / (double)caseCount); + int pos = 0; + DataList::iterator it; + for( it = data.begin(); it != data.end(); ++it ) + { + fprintf(f, "%d;%.4f\n", ++pos, *it); + } + fclose(f); + } + +private: + typedef QList<double> DataList; + + DataList data; + bool running; + struct timeval start; + struct timeval end; + + + void timevalSub(struct timeval *a, struct timeval *b, struct timeval *diff) + { + diff->tv_sec = a->tv_sec - b->tv_sec; + if( a->tv_usec < b->tv_usec ) + { + diff->tv_sec--; + diff->tv_usec = 1000000 - b->tv_usec + a->tv_usec; + } + else + diff->tv_usec = a->tv_usec - b->tv_usec; + } +}; + +class Client : public QObject +{ + Q_OBJECT + +public: + static uint32_t parseResourceList(QString resourceListStr); + +public: + Client(int testCnt, QString appClass, uint32_t all, uint32_t optional); + ~Client(); + + bool initialize(); + bool cleanup(); + int getFailed() { return failed; } + + double getAcquireAverage() { return timeStatAcq.totalTime / (double)timeStatAcq.caseCount; } + double getReleaseAverage() { return timeStatRel.totalTime / (double)timeStatRel.caseCount; } + +private slots: + void resourceAcquiredHandler(const QList<ResourcePolicy::ResourceType>& grantedResList); + void resourceDeniedHandler(); + void resourceLostHandler(); + void resourceReleasedHandler(); + +protected: + void timerEvent(QTimerEvent *e); + +private: + enum TestState + { + TestFinished = 0, + TestStart, + TestAcquire, + TestRelease, + TestWaiting + }; + + QString reportAcquire; + QString reportRelease; + TestState testState; + int testCounter; + int mainTimerID; + QString applicationClass; + TimeStat timeStatAcq; + TimeStat timeStatRel; + TimeStat timeStatTotal; + bool firstTime; + + uint32_t allResources; + uint32_t optionalResources; + + int failed; + int totalTestCount; + + ResourcePolicy::ResourceSet* resourceSet; + + ResourcePolicy::Resource* allocateResource(ResourcePolicy::ResourceType resource, bool optional); + ResourcePolicy::ResourceType getResourceType(uint32_t resource); + + void createSet(uint32_t list, uint32_t optional); +}; + +#endif diff --git a/tests/test-performance/test-resourceqt-performance/test-resourceqt-performance.cpp b/tests/test-performance/test-resourceqt-performance/test-resourceqt-performance.cpp new file mode 100644 index 0000000..69648b0 --- /dev/null +++ b/tests/test-performance/test-resourceqt-performance/test-resourceqt-performance.cpp @@ -0,0 +1,116 @@ +#include <QtCore/QCoreApplication> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <stdlib.h> +#include <errno.h> +#include <libgen.h> +#include <getopt.h> +#include "client.h" + +class ConfigParser +{ +public: + ConfigParser() + { + exitCode = 0; + exitFlag = false; + + resourcesAll = 0; + resourcesOptional = 0; + repeatCount = 100; + + parseConfig(); + } + +public: + bool exitFlag; + int exitCode; + + int repeatCount; + uint32_t resourcesAll; + uint32_t resourcesOptional; + double timeLimit; + QString applicationClass; + +private: + void parseConfig() + { + QSettings settings("/usr/lib/libresourceqt-performance-tests/test-resourceqt-performance.ini", QSettings::IniFormat); + + settings.beginGroup("config"); + QString resAll = settings.value("AllResources", "AudioPlayback,VideoPlayback").toString(); + QString resOpt = settings.value("OptionalResources", "").toString(); + QString appClass = settings.value("ApplicationClass", "player").toString().toLower(); + repeatCount = settings.value("TestCount", 100).toInt(); + settings.endGroup(); + + settings.beginGroup("main"); + timeLimit = settings.value("limit", 80.0).toDouble(); + settings.endGroup(); + + resourcesAll = Client::parseResourceList(resAll); + resourcesOptional = Client::parseResourceList(resOpt); + applicationClass = parseClassString(qPrintable(appClass)); + + if( applicationClass.isEmpty() ) + { + printf("Wrong application class in configuration file! Using default ...\n"); + applicationClass = "player"; + } + + if( !resourcesAll ) + { + resAll = "AudioPlayback,VideoPlayback"; + resourcesAll = Client::parseResourceList(resAll); + + printf("No resources found in configuration file! Using defaults ...\n"); + } + + if( (resourcesAll | resourcesOptional) != resourcesAll ) + { + printf("Optional resources are not subset of all resources!\n"); + exitFlag = true; + exitCode = 1; + } + } + + const char* parseClassString(const char *str) + { + if( strcmp(str, "call") && strcmp(str, "camera") && strcmp(str, "ringtone") && strcmp(str, "alarm") && strcmp(str, "navigator") && strcmp(str, "game") + && strcmp(str, "player") && strcmp(str, "event") && strcmp(str, "background") ) + { + printf("Invalid class '%s'", str); + return NULL; + } + + return str; + } +}; + +int main(int argc, char *argv[]) +{ + ConfigParser parser; + + if( parser.exitFlag ) + return parser.exitCode; + + QCoreApplication app(argc, argv); + Client client(parser.repeatCount, parser.applicationClass, parser.resourcesAll, parser.resourcesOptional); + app.exec(); + + int retval = client.getFailed(); + if( retval > 0 ) + printf("One or more test iterations failed!\n"); + + int oldval = retval; + retval += client.getAcquireAverage() > parser.timeLimit ? 100 : 0; + if( retval > oldval ) + printf("Acquire average time is higher than limit (%.2f/%.2f ms) !\n", client.getAcquireAverage(), parser.timeLimit); + + oldval = retval; + retval += client.getReleaseAverage() > parser.timeLimit ? 100 : 0; + if( retval > oldval ) + printf("Release average time is higher than limit (%.2f/%.2f ms) !\n", client.getReleaseAverage(), parser.timeLimit); + + return retval; +} diff --git a/tests/test-performance/test-resourceqt-performance/test-resourceqt-performance.pro b/tests/test-performance/test-resourceqt-performance/test-resourceqt-performance.pro new file mode 100644 index 0000000..01c9573 --- /dev/null +++ b/tests/test-performance/test-resourceqt-performance/test-resourceqt-performance.pro @@ -0,0 +1,24 @@ +include(../../../common.pri) + +TEMPLATE = app +TARGET = test-resourceqt-performance +MOC_DIR = .moc +OBJECTS_DIR = .obj +DEPENDPATH += . +QT = core +CONFIG += console +CONFIG -= app_bundle + +INCLUDEPATH += $${LIBRESOURCEINC} +QMAKE_CXXFLAGS += -Wall +LIBS += -L$${LIBRESOURCEQT}/build -lresourceqt -L$${LIBDBUSQEVENTLOOP}/build -ldbus-qeventloop + +# Input +HEADERS = client.h +SOURCES += test-resourceqt-performance.cpp client.cpp + +QMAKE_DISTCLEAN += -r .moc .obj + +# Install options +target.path = /usr/lib/libresourceqt-performance-tests/ +INSTALLS = target |