1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/fbs/fontandbitmapserver/tfbs/tfbsbase.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,262 @@
1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +/**
1.20 + @file
1.21 + @test
1.22 + @internalComponent - Internal Symbian test code
1.23 +*/
1.24 +
1.25 +#include "tfbsbase.h"
1.26 +#include "fbsmessage.h"
1.27 +
1.28 +CTFbsBase::CTFbsBase(CTestStep* aStep, TBool aRunWithLowMemory):
1.29 + CTGraphicsBase(aStep),
1.30 + iTestStep(*aStep),
1.31 + iLastTestCase(EFalse),
1.32 + iRunWithLowMemory(aRunWithLowMemory)
1.33 + {
1.34 + }
1.35 +
1.36 +CTFbsBase::~CTFbsBase()
1.37 + {
1.38 + }
1.39 +
1.40 +/** Run the passed the test case. Classes that inherit from CTFbsBase should override this
1.41 +and choose which test case to run depending on the passed test case number. Test cases are
1.42 +run once normally, 1..n times with out of memory (OOM) testing switched on for the FBServ
1.43 +heap and 1..n times with OOM testing switched on for the current heap.
1.44 +
1.45 +@param aCurTestCase The number of the test case to run
1.46 + */
1.47 +void CTFbsBase::RunTestCaseL(TInt aCurTestCase)
1.48 + {
1.49 + if(iLastTestCase)
1.50 + {
1.51 + TestComplete();
1.52 + return;
1.53 + }
1.54 +
1.55 + INFO_PRINTF2(_L("***** Starting test case %i *****"), aCurTestCase);
1.56 +
1.57 + // Run the test normally first
1.58 + iCurrentRunIsLowMemory = EFalse;
1.59 + TRAPD(err, RunFbsTestL(aCurTestCase));
1.60 + if(KErrNone != err)
1.61 + {
1.62 + iTestStep.SetTestStepResult(EFail);
1.63 + }
1.64 +
1.65 +#ifndef _DEBUG
1.66 + if(iRunWithLowMemory)
1.67 + {
1.68 + iRunWithLowMemory = EFalse;
1.69 + INFO_PRINTF1(_L("WARNING: Can't run out of memory tests under a release build. OOM tests set to run in ini file so turning OOM tests off."));
1.70 + }
1.71 +#endif
1.72 +
1.73 + // Run the test in out of memory conditions, checking both the FBServ heap and the
1.74 + // current thread's heap for memory leaks
1.75 + if(iRunWithLowMemory)
1.76 + {
1.77 + iCurrentRunIsLowMemory = ETrue;
1.78 + RFbsSession* fbsSession = RFbsSession::GetSession();
1.79 + ASSERT(fbsSession);
1.80 +
1.81 + INFO_PRINTF2(_L("***** Running Out Of Memory Tests on test case %i (FBSERV heap) *****"), aCurTestCase);
1.82 +
1.83 + // Save the current state of test step results
1.84 + TVerdict currentTestStepResult = iTestStep.TestStepResult();
1.85 +
1.86 + // Create 1000 pixel wide bitmap to prevent allocation of scanline buffer
1.87 + // during testings, to allow for memory leak testing
1.88 + const TSize KSizeInPixels = TSize(1000,1);
1.89 + const TDisplayMode KDisplayMode = EColor64K;
1.90 + CFbsBitmap* bmp = new(ELeave) CFbsBitmap;
1.91 + CleanupStack::PushL(bmp);
1.92 + User::LeaveIfError(bmp->Create(KSizeInPixels, KDisplayMode));
1.93 + CleanupStack::PopAndDestroy(bmp);
1.94 +
1.95 + // Run the test with heap checking for the FbServ heap
1.96 + for(TInt failAfter=1; failAfter < 1000; ++failAfter)
1.97 + {
1.98 + INFO_PRINTF2(_L("***** Set fail after %i allocs (FBSERV heap) *****"), failAfter);
1.99 +
1.100 + // Count cells so we can know if any leaked
1.101 + TInt cellsStart = fbsSession->SendCommand(EFbsMessHeapCount, RFbsSession::EHeapFailTypeHeapMemory);
1.102 + fbsSession->SendCommand(EFbsMessSetHeapFail, RFbsSession::EHeapFailTypeHeapMemory, failAfter);
1.103 +
1.104 + // Run test case (implemented by sub class)
1.105 + TRAPD(err, RunFbsTestL(aCurTestCase));
1.106 +
1.107 + fbsSession->SendCommand(EFbsMessSetHeapReset, RFbsSession::EHeapFailTypeHeapMemory);
1.108 + TInt cellsEnd = fbsSession->SendCommand(EFbsMessHeapCount, RFbsSession::EHeapFailTypeHeapMemory);
1.109 + if(cellsStart < cellsEnd)
1.110 + {
1.111 + // leaked.
1.112 + TInt leakedCells = cellsEnd - cellsStart;
1.113 + ERR_PRINTF3(_L("***** On loop number %i we leaked %i cells (FBSERV heap) *****"), failAfter, leakedCells);
1.114 + currentTestStepResult = EFail;
1.115 + }
1.116 +
1.117 + // Check to see if any failures reported within test case run
1.118 + if(KErrNone == err)
1.119 + {
1.120 + INFO_PRINTF3(_L("***** Test case %i completed successfully after %d iterations (FBSERV heap) *****"), aCurTestCase, failAfter);
1.121 + break;
1.122 + }
1.123 + }
1.124 +
1.125 + // Run the test with heap checking for the current thread's heap
1.126 + TInt tryCount = 0;
1.127 + INFO_PRINTF2(_L("***** Running Out Of Memory Tests on test case %i, current thread's heap (current heap) *****"), aCurTestCase);
1.128 +
1.129 + FOREVER
1.130 + {
1.131 + TInt err = KErrNone;
1.132 +
1.133 + // count cells so we can know how many we leaked
1.134 + TInt cellsStart = User::CountAllocCells();
1.135 + ++tryCount;
1.136 + INFO_PRINTF2(_L("***** Set fail after %d allocs (current heap) *****"), tryCount);
1.137 +
1.138 + __UHEAP_FAILNEXT(tryCount);
1.139 + __UHEAP_MARK;
1.140 +
1.141 + TRAP(err, RunFbsTestL(aCurTestCase));
1.142 +
1.143 + TBool finishedCorrectly = EFalse;
1.144 + if ((err == KErrNone))
1.145 + {
1.146 + // claims to have finished correctly, and we're not failing every alloc
1.147 + finishedCorrectly = iStep->CheckForHeapFailNext();
1.148 + }
1.149 + __UHEAP_RESET;
1.150 + TInt cellsEnd = User::CountAllocCells();
1.151 + if (cellsStart < cellsEnd)
1.152 + {
1.153 + // leaked.
1.154 + TInt leakedCells = cellsEnd - cellsStart;
1.155 + ERR_PRINTF3(_L("***** On loop number %d we leaked %d cells (current heap). About to cause panic."),tryCount,leakedCells);
1.156 + }
1.157 + __UHEAP_MARKEND;
1.158 +
1.159 + // check to see if we finished all OOM testing successfully
1.160 + if ((err == KErrNone) && finishedCorrectly)
1.161 + {
1.162 + INFO_PRINTF3(_L("***** Test case %i completed successfully after %d iterations (current heap) *****"), aCurTestCase, tryCount);
1.163 + break;
1.164 + }
1.165 +
1.166 + if (tryCount == 999)
1.167 + {
1.168 + ERR_PRINTF1(_L("***** OOM testing stopped after 999 iterations (current heap)"));
1.169 + break;
1.170 + }
1.171 + }
1.172 +
1.173 + // Restore test step result and ignore any test failures the out of memory tests produce
1.174 + iTestStep.SetTestStepResult(currentTestStepResult);
1.175 + }
1.176 + }
1.177 +
1.178 +/** Helper method for extracting a TRgb colour from the passed buffer given a pixel
1.179 +offset in to the buffer and a display mode.
1.180 +
1.181 +@param aBuffer A buffer to extract the colour from.
1.182 +@param aPixelOffset A pixel offset to use in to the buffer.
1.183 +@param aDispMode The display mode to use when converting the pixel colour to TRgb.
1.184 + */
1.185 +TRgb CTFbsBase::ExtractRgb(TUint8* aBuffer, TInt aPixelOffset, TDisplayMode aDispMode)
1.186 + {
1.187 + switch (aDispMode)
1.188 + {
1.189 + case EGray2:
1.190 + {
1.191 + TUint8 byte = *(aBuffer + (aPixelOffset >> 3));
1.192 + if (byte & (1 << (aPixelOffset & 7)))
1.193 + return KRgbWhite;
1.194 + return KRgbBlack;
1.195 + }
1.196 + case EGray4:
1.197 + {
1.198 + TUint8 byte = *(aBuffer + (aPixelOffset >> 2));
1.199 + byte >>= ((aPixelOffset & 3) << 1);
1.200 + return TRgb::Gray4(byte & 3);
1.201 + }
1.202 + case EGray16:
1.203 + {
1.204 + TUint8 byte = *(aBuffer + (aPixelOffset >> 1));
1.205 + if (aPixelOffset & 1)
1.206 + byte >>= 4;
1.207 + return TRgb::Gray16(byte & 0xf);
1.208 + }
1.209 + case EGray256:
1.210 + return TRgb::Gray256(*(aBuffer + aPixelOffset));
1.211 + case EColor16:
1.212 + {
1.213 + TUint8 byte = *(aBuffer + (aPixelOffset >> 1));
1.214 + if (aPixelOffset & 1)
1.215 + byte >>= 4;
1.216 + return TRgb::Color16(byte & 0xf);
1.217 + }
1.218 + case EColor256:
1.219 + return TRgb::Color256(*(aBuffer + aPixelOffset));
1.220 + case EColor4K:
1.221 + {
1.222 + TUint16 doubleByte = *(((TUint16*)aBuffer) + aPixelOffset);
1.223 + return TRgb::Color4K(doubleByte & 0xfff);
1.224 + }
1.225 + case EColor64K:
1.226 + {
1.227 + TUint16 doubleByte = *(((TUint16*)aBuffer) + aPixelOffset);
1.228 + return TRgb::Color64K(doubleByte);
1.229 + }
1.230 + case EColor16M:
1.231 + {
1.232 + aBuffer += aPixelOffset * 3;
1.233 + TInt value = *aBuffer++;
1.234 + value |= *aBuffer++ << 8;
1.235 + value |= *aBuffer << 16;
1.236 + return TRgb::Color16M(value);
1.237 + }
1.238 + case ERgb:
1.239 + return *(((TRgb*)aBuffer) + aPixelOffset);
1.240 + case EColor16MU:
1.241 + {
1.242 + return TRgb::Color16MU(*(((TUint32*)aBuffer) + aPixelOffset));
1.243 + }
1.244 + case EColor16MA:
1.245 + {
1.246 + return TRgb::Color16MA(*(((TUint32*)aBuffer) + aPixelOffset));
1.247 + }
1.248 + case EColor16MAP:
1.249 + {
1.250 + return TRgb::_Color16MAP(*(((TUint32*)aBuffer) + aPixelOffset));
1.251 + }
1.252 + default:
1.253 + break;
1.254 + };
1.255 + return KRgbBlack;
1.256 + }
1.257 +
1.258 +/** Function to be used by classes that inherit from CTFbsBase. SetLastTestCase()
1.259 +should be called after the last test case for a class is called to signal that
1.260 +testing has finished for that class.
1.261 + */
1.262 +void CTFbsBase::SetLastTestCase()
1.263 + {
1.264 + iLastTestCase = ETrue;
1.265 + }