--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cellular/telephonysettings/xqbindings/psetwrapper/tsrc/common/testutilities.cpp Tue Aug 31 15:45:17 2010 +0300
@@ -0,0 +1,251 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <QByteArray>
+#include "testutilities.h"
+
+/*!
+ Replaces global new operator for utilizing binary. Enables OOM
+ simulation and memory leak detection.
+
+ Note that creation of CBase derived Symbian classes
+ are not tracked, because CBase overloads new operator.
+ */
+void* operator new(std::size_t sz) throw(std::bad_alloc)
+{
+ return MemoryAllocator::alloc(sz);
+}
+
+/*!
+ Replaces global delete operator for utilizing binary. Enables OOM
+ simulation and memory leak detection.
+ */
+void operator delete(void* memoryAddr) throw()
+{
+ return MemoryAllocator::free(memoryAddr);
+}
+
+void* operator new(std::size_t sz, const std::nothrow_t&) throw()
+{
+ return qMalloc(sz);
+}
+
+void operator delete(void* memoryAddress, const std::nothrow_t&) throw()
+{
+ if (NULL != memoryAddress) {
+ qFree(memoryAddress);
+ }
+}
+
+bool MemoryAllocator::m_isOomSimulationEnabled = false;
+int MemoryAllocator::m_numOfAllocsSinceLastFail = 0;
+int MemoryAllocator::m_allocFailIndex = 1;
+QList<void*> MemoryAllocator::m_allocList;
+
+/*!
+ MemoryAllocator::enableOomSimulation
+ */
+void MemoryAllocator::enableOomSimulation()
+{
+ m_isOomSimulationEnabled = true;
+ m_allocFailIndex = 1;
+ m_numOfAllocsSinceLastFail = 0;
+}
+
+/*!
+ MemoryAllocator::disableOomSimulation
+ */
+void MemoryAllocator::disableOomSimulation()
+{
+ m_isOomSimulationEnabled = false;
+}
+
+/*!
+ MemoryAllocator::isOomSimulationEnabled
+ */
+bool MemoryAllocator::isOomSimulationEnabled()
+{
+ return m_isOomSimulationEnabled;
+}
+
+/*!
+ MemoryAllocator::currentAllocFailIndex
+ */
+int MemoryAllocator::currentAllocFailIndex()
+{
+ return m_allocFailIndex;
+}
+
+/*!
+ MemoryAllocator::alloc
+ */
+void* MemoryAllocator::alloc(std::size_t sz)
+{
+ if (isOomSimulationEnabled()) {
+ m_numOfAllocsSinceLastFail++;
+ if (m_allocFailIndex == m_numOfAllocsSinceLastFail) {
+ m_allocFailIndex++;
+ m_numOfAllocsSinceLastFail = 0;
+#ifdef QT_NO_EXCEPTIONS
+ return NULL;
+#else
+ throw std::bad_alloc();
+#endif
+ }
+ }
+
+ void *allocatedMemoryAddr = qMalloc(sz);
+ m_allocList.append(allocatedMemoryAddr);
+ return allocatedMemoryAddr;
+}
+
+/*!
+ MemoryAllocator::free
+ */
+void MemoryAllocator::free(void *memoryAddress)
+{
+ if (memoryAddress) {
+ int index = m_allocList.indexOf(memoryAddress);
+ if (-1 != index) {
+ m_allocList.removeAt(index);
+ }
+ qFree(memoryAddress);
+ }
+}
+
+/*!
+ MemoryAllocator::verifyMemoryAllocations
+ */
+void MemoryAllocator::verifyMemoryAllocations()
+{
+ int numOfUnfreedCells = m_allocList.count();
+ if (0 != numOfUnfreedCells) {
+ for ( int i = 0; i < numOfUnfreedCells; i++) {
+ qDebug("UNFREED CELL: %x", reinterpret_cast<int>(m_allocList.at(i)));
+ }
+
+ m_allocList.clear();
+ throw std::bad_alloc();
+ }
+
+ m_allocList.clear();
+}
+
+
+/*!
+ OomTestExecuter::runTest
+ */
+void OomTestExecuter::runTest(
+ QObject &testObject, const char *testMethod)
+{
+ qDebug() << "OomTestExecuter::runTest : IN :" << testMethod;
+
+ MemoryAllocator::enableOomSimulation();
+
+ bool exceptionCaught = false;
+ do {
+ exceptionCaught = false;
+ int currentAllocFailIndex = MemoryAllocator::currentAllocFailIndex();
+
+ try {
+ try {
+ QMetaObject::invokeMethod(
+ &testObject, "init", Qt::DirectConnection);
+ QMetaObject::invokeMethod(
+ &testObject, testMethod, Qt::DirectConnection);
+ } catch (const std::bad_alloc &ex) {
+ exceptionCaught = true;
+ QMetaObject::invokeMethod(
+ &testObject, "cleanup", Qt::DirectConnection);
+ }
+ // TODO: for some reason bad_alloc exception is corrupted to
+ // unknown exception and nested catch block is needed to be able to
+ // handle situation. One level catch does not work for some reason.
+ } catch (...) {
+ exceptionCaught = true;
+ QMetaObject::invokeMethod(
+ &testObject, "cleanup", Qt::DirectConnection);
+ if (currentAllocFailIndex == MemoryAllocator::currentAllocFailIndex()) {
+ qDebug() << "OomTestExecuter::runTest, ERROR: unexpected exception!";
+ throw;
+ }
+ }
+ } while(exceptionCaught);
+
+ QMetaObject::invokeMethod(&testObject, "cleanup", Qt::DirectConnection);
+ MemoryAllocator::disableOomSimulation();
+ qDebug() << "OomTestExecuter::runTest : OUT :" << testMethod;
+}
+
+/*!
+ OomTestExecuter::runAllTests
+ */
+void OomTestExecuter::runAllTests(
+ QObject &testObject, const char *callingTestMethod)
+{
+ const QMetaObject *metaObject = testObject.metaObject();
+
+ int methodCount = metaObject->methodCount();
+ for (int i = 0; i < methodCount; ++i) {
+ QMetaMethod slotMethodCandidate = metaObject->method(i);
+ if (!isValidSlot(slotMethodCandidate)) {
+ continue;
+ }
+
+ QByteArray slotMethodName(slotMethodCandidate.signature());
+ // remove parentheses
+ slotMethodName = slotMethodName.left(slotMethodName.length() - 2);
+
+ // Prevent from infinite loop and do not execute test method, which
+ // has called runAllTests.
+ if (slotMethodName != callingTestMethod) {
+ runTest(testObject, slotMethodName);
+ }
+ }
+}
+
+/*!
+ OomTestExecuter::isValidSlot
+ */
+bool OomTestExecuter::isValidSlot(const QMetaMethod &sl)
+{
+ if ((sl.access() != QMetaMethod::Private) || !sl.parameterTypes().isEmpty()
+ || qstrlen(sl.typeName()) || (sl.methodType() != QMetaMethod::Slot)) {
+ return false;
+ }
+
+ const char *sig = sl.signature();
+ int len = qstrlen(sig);
+ if (len < 2) {
+ return false;
+ }
+
+ if (sig[len - 2] != '(' || sig[len - 1] != ')') {
+ return false;
+ }
+
+ if (len > 7 && strcmp(sig + (len - 7), "_data()") == 0) {
+ return false;
+ }
+
+ if ((strcmp(sig, "initTestCase()") == 0) || (strcmp(sig, "cleanupTestCase()") == 0)
+ || (strcmp(sig, "cleanup()") == 0) || (strcmp(sig, "init()") == 0)) {
+ return false;
+ }
+
+ return true;
+}