From 8eaa6b90633a3696dbb30245a92a65b084b53c34 Mon Sep 17 00:00:00 2001 From: Murray Read Date: Thu, 26 Jan 2012 12:31:35 +0000 Subject: Fix exception handling testing on Symbian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Symbian autotest tst_qmainexceptions has been upgraded to run on hardware. Task-number: ou1cimx1#970701 Change-Id: Ia96ebdafb92c986599032c59528ed8633e3bec6c Reviewed-by: Murray Read Reviewed-by: Shane Kearns (cherry picked from commit dd36b63ccac0026ac0a22681052e88cff8258923) Reviewed-by: Pasi Pentikäinen --- .../qmainexceptions/tst_qmainexceptions.cpp | 153 ++++++++++++++++++--- 1 file changed, 137 insertions(+), 16 deletions(-) diff --git a/tests/auto/symbian/qmainexceptions/tst_qmainexceptions.cpp b/tests/auto/symbian/qmainexceptions/tst_qmainexceptions.cpp index d28995d3ce..5ccfdabbd3 100644 --- a/tests/auto/symbian/qmainexceptions/tst_qmainexceptions.cpp +++ b/tests/auto/symbian/qmainexceptions/tst_qmainexceptions.cpp @@ -47,6 +47,99 @@ #ifdef Q_OS_SYMBIAN +struct QAllocFailAllocator : public RAllocator +{ + QAllocFailAllocator() : allocator(User::Allocator()), allocCount(0), failNext(0) + { + User::SwitchAllocator(this); + } + + ~QAllocFailAllocator() + { + User::SwitchAllocator(&allocator); + } + + RAllocator& allocator; + int allocCount; + int failNext; + + TAny* CheckPtr(TAny* a) + { + if (a) + allocCount++; + return a; + } + + bool CheckFail() + { + if (failNext > 0) { + failNext--; + return true; + } + return false; + } + + // from MAllocator + TAny* Alloc(TInt aSize) + { + if (CheckFail()) + return 0; + return CheckPtr(allocator.Alloc(aSize)); + } + + void Free(TAny* aPtr) + { + if (aPtr) + allocCount--; + allocator.Free(aPtr); + } + + TAny* ReAlloc(TAny* aPtr, TInt aSize, TInt aMode) + { + if (CheckFail()) + return 0; + return allocator.ReAlloc(aPtr, aSize, aMode); + } + + TInt AllocLen(const TAny* aCell) const + { + return allocator.AllocLen(aCell); + } + + TInt Compress() + { + return allocator.Compress(); + } + + void Reset() + { + allocator.Reset(); + } + + TInt AllocSize(TInt& aTotalAllocSize) const + { + return allocator.AllocSize(aTotalAllocSize); + } + + TInt Available(TInt& aBiggestBlock) const + { + return allocator.Available(aBiggestBlock); + } + + TInt DebugFunction(TInt aFunc, TAny* a1, TAny* a2) + { + return allocator.DebugFunction(aFunc, a1, a2); + } + + TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1) + { + return ((MAllocator&)allocator).Extension_(aExtensionId, a0, a1); + } +}; + +QAllocFailAllocator testAllocator; + + typedef void TLeavingFunc(); class tst_qmainexceptions : public QObject @@ -99,35 +192,35 @@ void tst_qmainexceptions::trap() void tst_qmainexceptions::cleanupstack() { - __UHEAP_MARK; + int mark = testAllocator.allocCount; //fails if OOM CDummy* dummy1 = new (ELeave) CDummy; - __UHEAP_CHECK(1); + QCOMPARE(mark+1, testAllocator.allocCount); CleanupStack::PushL(dummy1); CleanupStack::PopAndDestroy(dummy1); - __UHEAP_MARKEND; + QCOMPARE(mark, testAllocator.allocCount); } void tst_qmainexceptions::leave() { - __UHEAP_MARK; + int mark = testAllocator.allocCount; CDummy* dummy1 = 0; TRAPD(err,{ CDummy* csDummy = new (ELeave) CDummy; CleanupStack::PushL(csDummy); - __UHEAP_FAILNEXT(1); + testAllocator.failNext = 1; dummy1 = new (ELeave) CDummy; //CleanupStack::PopAndDestroy(csDummy); not executed as previous line throws }); QCOMPARE(err,KErrNoMemory); QVERIFY(!((int)dummy1)); - __UHEAP_MARKEND; + QCOMPARE(mark, testAllocator.allocCount); } class CTestActive : public CActive { public: - CTestActive(TLeavingFunc* aFunc) : CActive(EPriorityStandard), iFunc(aFunc) + CTestActive(TLeavingFunc* aFunc, bool qtLoop = false) : CActive(EPriorityStandard), iFunc(aFunc), useQtLoop(qtLoop) { CActiveScheduler::Add(this); } @@ -142,30 +235,57 @@ public: TRequestStatus* s = &iStatus; SetActive(); User::RequestComplete(s, KErrNone); - CActiveScheduler::Start(); + StartLoop(); } void RunL() { + cleanedUp = false; + CleanupStack::PushL(TCleanupItem(CleanUp, &cleanedUp)); (*iFunc)(); - CActiveScheduler::Stop(); // will only get here if iFunc does not leave + CleanupStack::Pop(); + StopLoop(); // will only get here if iFunc does not leave } TInt RunError(TInt aError) { error = aError; - CActiveScheduler::Stop(); // will only get here if iFunc leaves + StopLoop(); // will only get here if iFunc leaves return KErrNone; } + void StartLoop() + { + if (useQtLoop) + qEventLoop.exec(); + else + CActiveScheduler::Start(); + } + void StopLoop() + { + if (useQtLoop) + qEventLoop.exit(); + else + CActiveScheduler::Stop(); + } + static void CleanUp(TAny* cleanedUpFlag) + { + *((bool*)cleanedUpFlag) = true; + } public: TLeavingFunc* iFunc; int error; + bool useQtLoop; + bool cleanedUp; + QEventLoop qEventLoop; }; void tst_qmainexceptions::TestSchedulerCatchesError(TLeavingFunc* f, int error) { - CTestActive *act = new(ELeave) CTestActive(f); - act->Test(); - QCOMPARE(act->error, error); - delete act; + for (int i=0; i<2; i++) { + CTestActive *act = new(ELeave) CTestActive(f, i==1); + act->Test(); + QCOMPARE(act->error, error); + QVERIFY(act->cleanedUp); + delete act; + } } void ThrowBadAlloc() @@ -312,14 +432,15 @@ void tst_qmainexceptions::testDtor2() { // memory is cleaned up correctly on exception // this crashes with winscw compiler build < 481 - __UHEAP_MARK; + int mark = testAllocator.allocCount; try { + QScopedPointer ptr(new QString("abc")); QString str("abc"); str += "def"; throw std::bad_alloc(); QFAIL("should not get here"); } catch (const std::bad_alloc&) { } - __UHEAP_MARKEND; + QCOMPARE(mark, testAllocator.allocCount); } void tst_qmainexceptions::testNestedExceptions() -- cgit v1.2.1