sl@0: // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include "srvrepos_noc.h" sl@0: #include "srvres.h" sl@0: #include "cachemgr.h" sl@0: #include "sessnotf.h" sl@0: sl@0: RTest TheTest(_L("Central Repository Coarse-Grained Cache Tests")); sl@0: sl@0: enum TBorderTestStage sl@0: { sl@0: ENominalNoFile = -1, sl@0: ENominal = 0, sl@0: ESizeMin, sl@0: ESizeMinplus, sl@0: ESizeMaxminus, sl@0: ESizeMax, sl@0: ESizeMaxplus, sl@0: ETimeoutMin, sl@0: ETimeoutMinplus, sl@0: ETimeoutMaxminus, sl@0: EReallyWorstCase, sl@0: ELastStage sl@0: }; sl@0: sl@0: const TUid KUidCacheTestRepositorySm = { 0x00000002 }; sl@0: const TUid KUidCacheTestRepositorySm2 = { 0x00000011 }; sl@0: const TUid KUidCacheTestRepositoryMed = { 0x11111111 }; sl@0: const TUid KUidCacheTestRepositoryMed2 = { 0x00057778 }; sl@0: const TUid KUidCacheTestRepositoryLrg = { 0xCCCCCC01 }; sl@0: sl@0: const TInt KTimerDelay = 1000000; sl@0: const TInt KMemoryFiller = 3762; sl@0: sl@0: _LIT(KCacheMgrIniFileFolder, "\\private\\10202BE9\\"); sl@0: _LIT(KCacheMgrIniSrcFile, "centrepcache.ini"); sl@0: sl@0: TTime starttime; sl@0: sl@0: class TRepositoryCacheManagerTester sl@0: { sl@0: public: sl@0: TRepositoryCacheManagerTester(): iOOMTest(EFalse), iStage(ENominalNoFile), iTestStepStage(0) sl@0: { sl@0: iFs.Connect(); sl@0: } sl@0: ~TRepositoryCacheManagerTester() sl@0: { sl@0: iFs.Close(); sl@0: } sl@0: TInt CacheRepositoryL(TUid aRepUid, TBool& aTrap); sl@0: TInt CacheRepositoryL(TUid aRepUid); sl@0: TBool FindRepository(TUid aRepUid); sl@0: void FuncTestsL(); sl@0: void SizeTestsL(); sl@0: void TimingTestsL(); sl@0: void DefectTestsL(); sl@0: void DEF093491L(); sl@0: void INC105967(); sl@0: void DeleteFilesL(); sl@0: void DEF111734L(); sl@0: void DEF124147(); sl@0: void InstallIniFileL( TBorderTestStage aFileSet ); sl@0: void AdvanceToStageL(TBorderTestStage aStage); sl@0: void NextTest(TPtrC aMsg); sl@0: static TInt Callback(TAny* aParent); sl@0: static void CleanUp(TAny*); sl@0: public: sl@0: TBool iOOMTest; sl@0: RFs iFs; sl@0: TBorderTestStage iStage; sl@0: TInt iTestStepStage; sl@0: }; sl@0: sl@0: LOCAL_C TRepositoryCacheManagerTester Tester; sl@0: sl@0: LOCAL_C TCleanupItem gCleanup(TRepositoryCacheManagerTester::CleanUp); sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: //Test macroses and functions sl@0: sl@0: void TRepositoryCacheManagerTester::DeleteFilesL() sl@0: { sl@0: _LIT( KOldInstallFiles, "c:\\private\\10202BE9\\*.ini" ); sl@0: sl@0: CFileMan* fm = CFileMan::NewL( iFs ); sl@0: CleanupStack::PushL( fm ); sl@0: sl@0: TInt r = fm->Delete( KOldInstallFiles ); sl@0: if ( r != KErrNone && r != KErrNotFound && r != KErrPathNotFound ) sl@0: User::Leave(r); sl@0: sl@0: CleanupStack::PopAndDestroy( fm ); sl@0: } sl@0: sl@0: LOCAL_C void Check( TInt aValue, TInt aLine ) sl@0: { sl@0: if ( !aValue ) sl@0: { sl@0: TheTest( EFalse, aLine ); sl@0: } sl@0: } sl@0: sl@0: LOCAL_C void Check( TInt aValue, TInt aExpected, TInt aLine ) sl@0: { sl@0: if ( aValue != aExpected ) sl@0: { sl@0: RDebug::Print( _L( "*** Expected error: %d, got: %d\r\n"), aExpected, aValue ); sl@0: TheTest( EFalse, aLine ); sl@0: } sl@0: } sl@0: sl@0: #define TEST(arg) ::Check((arg), __LINE__) sl@0: #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__) sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void TRepositoryCacheManagerTester::NextTest(TPtrC aMsg) sl@0: { sl@0: if (!iOOMTest) sl@0: { sl@0: TheTest.Next( aMsg ); sl@0: } sl@0: } sl@0: sl@0: void TRepositoryCacheManagerTester::AdvanceToStageL(TBorderTestStage aStage) sl@0: { sl@0: iStage = aStage; sl@0: if (aStage != ENominalNoFile) sl@0: { sl@0: InstallIniFileL( aStage ); sl@0: } sl@0: else sl@0: { sl@0: DeleteFilesL(); sl@0: } sl@0: delete TServerResources::iCacheManager; sl@0: TServerResources::iCacheManager = NULL; sl@0: TServerResources::iCacheManager = CRepositoryCacheManager::NewLC(iFs); sl@0: CleanupStack::Pop(TServerResources::iCacheManager); sl@0: } sl@0: sl@0: void TRepositoryCacheManagerTester::InstallIniFileL( TBorderTestStage aFileSet ) sl@0: { sl@0: _LIT( KDriveC, "c:" ); sl@0: _LIT( KDriveZ, "z:" ); sl@0: sl@0: TBuf src1; sl@0: TBuf dest1; sl@0: TInt r; sl@0: sl@0: DeleteFilesL(); sl@0: sl@0: CFileMan* fm = CFileMan::NewL( iFs ); sl@0: CleanupStack::PushL( fm ); sl@0: sl@0: if ((aFileSet>=ELastStage)||(aFileSet<0)) sl@0: { sl@0: RDebug::Print( _L( "Illegal parameter to function: %d\r\n" ), aFileSet ); sl@0: TheTest( EFalse, __LINE__ ); sl@0: } sl@0: else sl@0: { sl@0: dest1.Copy( KDriveC ); sl@0: dest1.Append( KCacheMgrIniFileFolder ); sl@0: dest1.Append( KCacheMgrIniFile ); sl@0: r = fm->Delete( dest1 ); sl@0: if ( r != KErrNone && r != KErrNotFound && r != KErrPathNotFound ) sl@0: User::Leave( r ); sl@0: r = iFs.MkDirAll( dest1 ); sl@0: if ( r != KErrNone && r != KErrAlreadyExists ) sl@0: User::Leave( r ); sl@0: src1.Copy( KDriveZ ); sl@0: src1.Append( KCacheMgrIniFileFolder ); sl@0: src1.Append( KCacheMgrIniSrcFile ); sl@0: TBuf<2> testNo; sl@0: testNo.Num(aFileSet); sl@0: src1.Append( testNo ); sl@0: User::LeaveIfError( fm->Copy( src1, dest1 ) ); sl@0: r = fm->Attribs( dest1, KEntryAttArchive, KEntryAttReadOnly, TTime( 0 ), CFileMan::ERecurse ); sl@0: TEST2( r, KErrNone ); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy( fm ); sl@0: } sl@0: sl@0: TInt TRepositoryCacheManagerTester::CacheRepositoryL(TUid aRepUid) sl@0: { sl@0: TBool trap = EFalse; sl@0: return CacheRepositoryL(aRepUid, trap); sl@0: } sl@0: sl@0: void TRepositoryCacheManagerTester::CleanUp(TAny*) sl@0: { sl@0: // If cache manager is initialized and used before, we flush it sl@0: if (TServerResources::iCacheManager) sl@0: { sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: } sl@0: // To get rid of the iOpenRepositories array leaking problem during OOM testing. sl@0: TServerResources::iObserver->CloseiOpenRepositories(); sl@0: TServerResources::iObserver->Reset(); sl@0: // To get rid of the array leaking problems during OOM testing. sl@0: TServerResources::iOwnerIdLookUpTable.Reset(); sl@0: } sl@0: sl@0: // Opens and Closes a repository to place it in the cache sl@0: TInt TRepositoryCacheManagerTester::CacheRepositoryL(TUid aRepUid, TBool& aTrap) sl@0: { sl@0: TInt repsize = 0; sl@0: // Notifier needed to open repositories. sl@0: CSessionNotifier* notifier; sl@0: notifier = new(ELeave)CSessionNotifier; sl@0: CleanupStack::PushL(notifier); sl@0: sl@0: CServerRepository* repository = new(ELeave) CServerRepository(); sl@0: CleanupStack::PushL(repository); sl@0: TServerResources::iObserver->iTrapOOMOnOpen = aTrap; sl@0: aTrap = EFalse; // This means that this function didn't leave until attempting to open the repository sl@0: repository->OpenL(aRepUid,*notifier); sl@0: repsize = repository->SizeiRepository(); sl@0: repository->Close(); sl@0: TServerResources::iObserver->iTrapOOMOnOpen = EFalse; sl@0: sl@0: CleanupStack::PopAndDestroy(repository); sl@0: CleanupStack::PopAndDestroy(notifier); sl@0: sl@0: return repsize; sl@0: } sl@0: sl@0: // Checks if a repository is in the cache sl@0: TBool TRepositoryCacheManagerTester::FindRepository(TUid aRepUid) sl@0: { sl@0: for(TInt i=TServerResources::iCacheManager->iIdleRepositories.Count()-1; i>=0; i--) sl@0: { sl@0: if(TServerResources::iCacheManager->iIdleRepositories[i].iSharedRepository->Uid()==aRepUid) sl@0: { sl@0: return ETrue; sl@0: } sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: TInt TRepositoryCacheManagerTester::Callback(TAny* aParent) sl@0: { sl@0: TTime now; sl@0: now.UniversalTime(); sl@0: TheTest.Printf(_L("Timer Expired at %Ld\n"), now.MicroSecondsFrom(starttime).Int64()); sl@0: ((CPeriodic*)aParent)->Cancel();; sl@0: CActiveScheduler::Stop(); sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-1419 sl@0: @SYMTestCaseDesc Test Coarse-Grained Caching functionality. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Check correct initialization of the cache manager, expected caching behaviour after sl@0: repository open/close, correct setting of cache size, correct functioning of the cache flush sl@0: functionality, OOM recovery by cache flushing feature and cache Disable/Enable functionality sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMPREQ PREQ1192 sl@0: @SYMTestStatus Defined sl@0: @SYMDevelopedForRelease Symbian OS v9.3 sl@0: @SYMAuthor Aleks Pamir sl@0: */ sl@0: void TRepositoryCacheManagerTester::FuncTestsL() sl@0: { sl@0: NextTest(_L( " @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-1419 Initialize Cache Manager " )); sl@0: sl@0: iTestStepStage = 0; sl@0: TEST( TServerResources::iCacheManager != 0 ); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: TServerResources::iCacheManager->EnableCache(); sl@0: sl@0: NextTest( _L( "Cache Repository (Open/Close)" ) ); sl@0: sl@0: CacheRepositoryL(KUidCacheTestRepositorySm); sl@0: sl@0: if ((iStage == ESizeMin)||(iStage == EReallyWorstCase)) sl@0: { sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: } sl@0: else sl@0: { sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: } sl@0: sl@0: NextTest( _L( "Check Cache Size" ) ); sl@0: sl@0: if ((iStage == ESizeMin)||(iStage == EReallyWorstCase)) sl@0: { sl@0: TEST( TServerResources::iCacheManager->iTotalCacheUsage == 0 ); sl@0: } sl@0: else sl@0: { sl@0: TEST( TServerResources::iCacheManager->iTotalCacheUsage > 0 ); sl@0: } sl@0: sl@0: NextTest( _L( "Flush Cache" ) ); sl@0: sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: TEST( TServerResources::iCacheManager->iTotalCacheUsage == 0 ); sl@0: sl@0: sl@0: if (!iOOMTest) sl@0: { sl@0: // This test is excluded from generic OOM testing because sl@0: // 1. It is trying to simulate OOM condition in a different way (fillingup the memory with sl@0: // allocs) which makes it very tricky to work under normal OOM testing method sl@0: // 2. Loading Lrg repository within OOM takes forever because there're many allocations, and sl@0: // loading other repositories are already tested in other tests sl@0: sl@0: NextTest( _L( "Cache OOM Handling" ) ); sl@0: sl@0: // Fill cache with reps sl@0: TInt totalsize; sl@0: TInt cachedRepositoryCount = 0; sl@0: sl@0: totalsize = CacheRepositoryL(KUidCacheTestRepositorySm); sl@0: if (TServerResources::iCacheManager->iCacheSize >= totalsize) sl@0: { sl@0: cachedRepositoryCount++; sl@0: } sl@0: totalsize += CacheRepositoryL(KUidCacheTestRepositorySm2); sl@0: if (TServerResources::iCacheManager->iCacheSize >= totalsize) sl@0: { sl@0: cachedRepositoryCount++; sl@0: } sl@0: totalsize += CacheRepositoryL(KUidCacheTestRepositoryLrg); sl@0: if (TServerResources::iCacheManager->iCacheSize >= totalsize) sl@0: { sl@0: cachedRepositoryCount++; sl@0: } sl@0: totalsize += CacheRepositoryL(KUidCacheTestRepositoryMed2); sl@0: if (TServerResources::iCacheManager->iCacheSize >= totalsize) sl@0: { sl@0: cachedRepositoryCount++; sl@0: } sl@0: sl@0: TInt res = KErrNone; sl@0: // Fill Memory sl@0: TInt popCount=0; sl@0: RHeap& myHeap = User::Heap(); sl@0: TInt firstSize = myHeap.Size(); sl@0: TInt biggestBlock; sl@0: TInt firstAvail = myHeap.Available(biggestBlock); sl@0: sl@0: while(ETrue) sl@0: { sl@0: // We need to really fill up the memory, because we want it to be really freed when we explictly sl@0: // free it, so that when we alloc again there will be some free memory. Using debug allocfail sl@0: // tools would have been too artifical for such a test sl@0: TAny* dummy = User::Alloc(KMemoryFiller); sl@0: if (dummy) sl@0: { sl@0: popCount++; sl@0: TRAP( res, CleanupStack::PushL(dummy); CleanupStack::Pop(dummy);); sl@0: if (res == KErrNoMemory) sl@0: { sl@0: // If we cannot allocate enough memory for the cleanupstack frame, we also deallocate sl@0: // the last memory block. This is mandatory for the correct functioning of the sl@0: // following test cases sl@0: // Note when an object that is attempted to be PushL to the cleanupstack and it fails sl@0: // the object will be freed automatically. sl@0: popCount--; sl@0: break; sl@0: } sl@0: else sl@0: { sl@0: CleanupStack::PushL(dummy); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: firstSize = myHeap.Size(); sl@0: firstAvail = myHeap.Available(biggestBlock); sl@0: break; sl@0: } sl@0: }; sl@0: sl@0: // Test if cache is as full as it should be sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == cachedRepositoryCount ); sl@0: sl@0: // Try loading Med rep. Should Fail sl@0: TRAP( res, CacheRepositoryL(KUidCacheTestRepositoryMed)); sl@0: sl@0: TEST( res == KErrNoMemory ); sl@0: sl@0: // Cache is still as it was before attempting load sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == cachedRepositoryCount ); sl@0: sl@0: // Try loading Med rep with OOM trapping. sl@0: TBool oomtrap = ETrue; sl@0: TRAP( res, CacheRepositoryL(KUidCacheTestRepositoryMed, oomtrap)); sl@0: sl@0: if ((iStage == ESizeMin)||(iStage == EReallyWorstCase)) sl@0: { sl@0: // Should still fail because the cache was empty to begin with so there's nothing sl@0: // to evict and no memory to gain sl@0: TEST( res == KErrNoMemory ); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: } sl@0: else if (iStage == ESizeMinplus) sl@0: { sl@0: // Should still fail because although the cache was full, the amount of memory freed sl@0: // will not be enough for the medium repository sl@0: TEST( res == KErrNoMemory ); sl@0: if (oomtrap) sl@0: { sl@0: // Memory alloc failed even before open was attempted, so no cache flush happened sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == cachedRepositoryCount ); sl@0: } sl@0: else sl@0: { sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // Should Pass and evict repositories sl@0: TEST( res == KErrNone ); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(popCount); sl@0: } sl@0: sl@0: NextTest( _L( "Cache Disable/Enable" ) ); sl@0: sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: sl@0: TServerResources::iCacheManager->EnableCache(); sl@0: sl@0: CacheRepositoryL(KUidCacheTestRepositorySm); sl@0: if ((iStage == ESizeMin)||(iStage == EReallyWorstCase)) sl@0: { sl@0: // No cache sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: } sl@0: else sl@0: { sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: } sl@0: sl@0: TServerResources::iCacheManager->DisableCache(); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: CacheRepositoryL(KUidCacheTestRepositoryMed); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: TServerResources::iCacheManager->EnableCache(); sl@0: sl@0: NextTest( _L( "Multi Client Test" ) ); sl@0: sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: sl@0: // Creating two sets of server objects sl@0: CSessionNotifier* notifier = new(ELeave)CSessionNotifier; sl@0: CleanupStack::PushL(notifier); sl@0: sl@0: CServerRepository* repository = new(ELeave) CServerRepository(); sl@0: CleanupStack::PushL(repository); sl@0: sl@0: CSessionNotifier* notifier2 = new(ELeave)CSessionNotifier; sl@0: CleanupStack::PushL(notifier2); sl@0: sl@0: CServerRepository* repository2 = new(ELeave) CServerRepository(); sl@0: CleanupStack::PushL(repository2); sl@0: sl@0: // Open a rep with 1st client sl@0: repository->OpenL(KUidCacheTestRepositorySm,*notifier); sl@0: // Open same rep with 2nd client sl@0: repository2->OpenL(KUidCacheTestRepositorySm,*notifier2); sl@0: sl@0: // One repository is in the cache, because now(PREQ 1228) all repositories sl@0: // are moved to cache just after they are opened, not after they are closed. sl@0: if ((iStage == ESizeMin)||(iStage == EReallyWorstCase)) sl@0: { sl@0: // No cache sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: } sl@0: else sl@0: { sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: } sl@0: // First client closed sl@0: repository->Close(); sl@0: // Repository still in the cache sl@0: if ((iStage == ESizeMin)||(iStage == EReallyWorstCase)) sl@0: { sl@0: // No cache sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: } sl@0: else sl@0: { sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: } sl@0: // Second client closed sl@0: repository2->Close(); sl@0: sl@0: // One rep must still be in the cache now sl@0: if ((iStage == ESizeMin)||(iStage == EReallyWorstCase)) sl@0: { sl@0: // No cache sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: } sl@0: else sl@0: { sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: } sl@0: sl@0: NextTest( _L( "Notify-Only Client Cache Repository (Open Only)" ) ); sl@0: sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: TServerResources::iObserver->CloseiOpenRepositories(); sl@0: sl@0: // Open a rep with 1st client sl@0: repository->OpenL(KUidCacheTestRepositorySm,*notifier); sl@0: sl@0: if ((iStage == ESizeMin)||(iStage == EReallyWorstCase)) sl@0: { sl@0: // No memory, so no cache sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: // But it's open sl@0: TEST( TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) != KErrNotFound ); sl@0: } sl@0: else sl@0: { sl@0: // Repository should have been cached after open sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: // And it's open sl@0: TEST( TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) != KErrNotFound ); sl@0: } sl@0: sl@0: // First client closed sl@0: repository->Close(); sl@0: sl@0: if ((iStage == ESizeMin)||(iStage == EReallyWorstCase)) sl@0: { sl@0: // No memory, so no cache sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: // Now it's closed sl@0: TEST( TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) == KErrNotFound ); sl@0: } sl@0: else sl@0: { sl@0: // Still in cache because timeout hasn't occured sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: // And still open sl@0: TEST( TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) != KErrNotFound ); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(repository2); sl@0: CleanupStack::PopAndDestroy(notifier2); sl@0: CleanupStack::PopAndDestroy(repository); sl@0: CleanupStack::PopAndDestroy(notifier); sl@0: sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-1420 sl@0: @SYMTestCaseDesc Test Coarse-Grained Caching forced eviction rules. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Check correct initialization of the cache manager, disabling/enabling sl@0: cache with different cache size, filling, eventual forced eviction of repository under sl@0: small and large memory cases sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMPREQ PREQ1192 sl@0: @SYMTestStatus Defined sl@0: @SYMDevelopedForRelease Symbian OS v9.3 sl@0: @SYMAuthor Aleks Pamir sl@0: */ sl@0: void TRepositoryCacheManagerTester::SizeTestsL() sl@0: { sl@0: NextTest( _L( " @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-1420 Forced Eviction-Small cache " ) ); sl@0: sl@0: iTestStepStage = 1; sl@0: TEST( TServerResources::iCacheManager != 0 ); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: sl@0: // Flush and disable the cache sl@0: TServerResources::iCacheManager->DisableCache(ETrue); sl@0: sl@0: // Calculate cache size for this test. It's important to calculate this at runtime, sl@0: // because this size is approximate and it changes from emulator to hardware sl@0: sl@0: TServerResources::iCacheManager->EnableCache(KInvalidEvictionTimeout, KDefaultCacheSize); sl@0: sl@0: TInt smallCacheSize = CacheRepositoryL(KUidCacheTestRepositorySm); sl@0: smallCacheSize+= CacheRepositoryL(KUidCacheTestRepositoryMed); sl@0: smallCacheSize+= (CacheRepositoryL(KUidCacheTestRepositorySm2)/2); sl@0: sl@0: // smallCacheSize is KUidCacheTestRepositorySm+KUidCacheTestRepositoryMed+ half of KUidCacheTestRepositorySm2 sl@0: // the reason is we don't want KUidCacheTestRepositorySm2 to fit sl@0: sl@0: TServerResources::iCacheManager->DisableCache(ETrue); sl@0: //Change cache size sl@0: TServerResources::iCacheManager->EnableCache(KInvalidEvictionTimeout, smallCacheSize); sl@0: sl@0: // Fill cache sl@0: CacheRepositoryL(KUidCacheTestRepositorySm); sl@0: CacheRepositoryL(KUidCacheTestRepositoryMed); sl@0: User::After(KTimerDelay); sl@0: //This one will not fit, and the Small rep will be evicted because it's small sl@0: CacheRepositoryL(KUidCacheTestRepositorySm2); sl@0: sl@0: TEST( !FindRepository(KUidCacheTestRepositorySm) ); sl@0: TEST( FindRepository(KUidCacheTestRepositorySm2) ); sl@0: sl@0: TInt delay = TServerResources::iCacheManager->iDefaultTimeout.Int()-KTimerDelay; sl@0: // If timeout is smaller then KTimerDelay, don't bother to wait sl@0: if (delay>0) sl@0: { sl@0: User::After(delay); sl@0: } sl@0: //Medium will be evicted this time, because it's older and size difference doesn't make up for the time difference sl@0: CacheRepositoryL(KUidCacheTestRepositorySm); sl@0: sl@0: TEST( !FindRepository(KUidCacheTestRepositoryMed) ); sl@0: TEST( FindRepository(KUidCacheTestRepositorySm) ); sl@0: sl@0: if (!iOOMTest) sl@0: { sl@0: // This test is excluded from generic OOM testing because sl@0: // 1. Loading Lrg repository within OOM takes forever because there're many allocations, and sl@0: // the test is very similar to previous test sl@0: sl@0: NextTest( _L( "Forced Eviction-Large cache" ) ); sl@0: sl@0: TServerResources::iCacheManager->DisableCache(ETrue); sl@0: sl@0: TServerResources::iCacheManager->EnableCache(KInvalidEvictionTimeout, KDefaultCacheSize); sl@0: sl@0: TInt largeCacheSize = CacheRepositoryL(KUidCacheTestRepositoryMed); sl@0: largeCacheSize+= CacheRepositoryL(KUidCacheTestRepositoryLrg); sl@0: largeCacheSize+= (CacheRepositoryL(KUidCacheTestRepositoryMed2)/2); sl@0: sl@0: // smallCacheSize is KUidCacheTestRepositorySm+KUidCacheTestRepositoryMed+ half of KUidCacheTestRepositorySm2 sl@0: // the reason is we don't want KUidCacheTestRepositorySm2 to fit sl@0: sl@0: TServerResources::iCacheManager->DisableCache(ETrue); sl@0: sl@0: //Change Parameters sl@0: TServerResources::iCacheManager->EnableCache(KInvalidEvictionTimeout, largeCacheSize); sl@0: // Fill cache sl@0: CacheRepositoryL(KUidCacheTestRepositoryMed); sl@0: CacheRepositoryL(KUidCacheTestRepositoryLrg); sl@0: User::After(KTimerDelay); sl@0: //This one will not fit, and the Med rep will be evicted because it's small sl@0: CacheRepositoryL(KUidCacheTestRepositoryMed2); sl@0: sl@0: TEST( !FindRepository(KUidCacheTestRepositoryMed) ); sl@0: TEST( FindRepository(KUidCacheTestRepositoryLrg) ); sl@0: sl@0: delay = TServerResources::iCacheManager->iDefaultTimeout.Int()-KTimerDelay; sl@0: // If timeout is smaller then KTimerDelay, don't bother to wait sl@0: if (delay>0) sl@0: { sl@0: User::After(delay); sl@0: } sl@0: sl@0: //Medium2 will be evicted, because even if it's new, this time size difference makes up for the sl@0: //time difference and the Large repository stays even if it's older sl@0: CacheRepositoryL(KUidCacheTestRepositoryMed); sl@0: sl@0: TEST( !FindRepository(KUidCacheTestRepositoryMed2) ); sl@0: TEST( FindRepository(KUidCacheTestRepositoryLrg) ); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-1421 sl@0: @SYMTestCaseDesc Test Coarse-Grained Caching normal eviction rules. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Check correct initialization of the cache manager, adding repository into sl@0: cache and active object driven eviction at correct times. sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMPREQ PREQ1192 sl@0: @SYMTestStatus Defined sl@0: @SYMDevelopedForRelease Symbian OS v9.3 sl@0: @SYMAuthor Aleks Pamir sl@0: */ sl@0: void TRepositoryCacheManagerTester::TimingTestsL() sl@0: { sl@0: sl@0: iTestStepStage = 2; sl@0: sl@0: TEST( TServerResources::iCacheManager != 0 ); sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: sl@0: CPeriodic* timer = CPeriodic::NewL(EPriorityLow); sl@0: CleanupStack::PushL(timer); sl@0: sl@0: NextTest( _L( " @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-1421 Cache Timing(Component Test) " ) ); sl@0: sl@0: starttime.UniversalTime(); sl@0: // Add one repository in the cache sl@0: CacheRepositoryL(KUidCacheTestRepositorySm); sl@0: TTime now; sl@0: now.UniversalTime(); sl@0: TheTest.Printf(_L("KUidCacheTestRepositorySm Added at %Ld\n"), now.MicroSecondsFrom(starttime).Int64()); sl@0: sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: sl@0: // Wait until the repository is evicted normally sl@0: // We can't use User::After because we don't want to suspend the thread sl@0: timer->Start(TTimeIntervalMicroSeconds32(TServerResources::iCacheManager->iDefaultTimeout.Int()-KTimerDelay), 0, TCallBack(Callback, timer)); sl@0: sl@0: CActiveScheduler::Start(); sl@0: sl@0: // Callback should have been called before Cache timeout had occured sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: sl@0: starttime.UniversalTime(); sl@0: // Add another repository in the cache sl@0: CacheRepositoryL(KUidCacheTestRepositorySm2); sl@0: now.UniversalTime(); sl@0: TheTest.Printf(_L("KUidCacheTestRepositorySm2 added at %Ld\n"), now.MicroSecondsFrom(starttime).Int64()); sl@0: sl@0: // wait more than default timeout. sl@0: timer->Start(TTimeIntervalMicroSeconds32(TServerResources::iCacheManager->iDefaultTimeout.Int()+KTimerDelay), 0, TCallBack(Callback, timer)); sl@0: sl@0: CActiveScheduler::Start(); sl@0: sl@0: // Callback should have been called by now sl@0: TInt count = TServerResources::iCacheManager->iIdleRepositories.Count(); sl@0: if (count > 0) sl@0: { sl@0: // Do not fail test on emulator. CTimer::AtUTC is often sl@0: // late by 1 to a few seconds. sl@0: #if defined(__WINSCW__) || defined(__WINS__) sl@0: TheTest.Printf(_L("*** Line %d check fail. Ignored on winscw."), __LINE__); sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: #endif sl@0: } sl@0: sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: sl@0: NextTest( _L( "Notify-Only Client Timing Test" ) ); sl@0: sl@0: // Add one repository in the cache sl@0: CSessionNotifier* notifier = new(ELeave)CSessionNotifier; sl@0: CleanupStack::PushL(notifier); sl@0: sl@0: CServerRepository* repository = new(ELeave) CServerRepository(); sl@0: CleanupStack::PushL(repository); sl@0: sl@0: starttime.UniversalTime(); sl@0: sl@0: // Open a rep sl@0: repository->OpenL(KUidCacheTestRepositorySm,*notifier); sl@0: sl@0: now.UniversalTime(); sl@0: TheTest.Printf(_L("KUidCacheTestRepositorySm Added at %Ld\n"), now.MicroSecondsFrom(starttime).Int64()); sl@0: sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: sl@0: // Wait until the repository is evicted normally sl@0: // We can't use User::After because we don't want to suspend the thread sl@0: timer->Start(TTimeIntervalMicroSeconds32(TServerResources::iCacheManager->iDefaultTimeout.Int()-KTimerDelay), 0, TCallBack(Callback, timer)); sl@0: sl@0: CActiveScheduler::Start(); sl@0: sl@0: // Callback should have been called before Cache timeout had occured sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: sl@0: // Add another repository in the cache sl@0: // Add one repository in the cache sl@0: CSessionNotifier* notifier2 = new(ELeave)CSessionNotifier; sl@0: CleanupStack::PushL(notifier2); sl@0: sl@0: CServerRepository* repository2 = new(ELeave) CServerRepository(); sl@0: CleanupStack::PushL(repository2); sl@0: sl@0: starttime.UniversalTime(); sl@0: sl@0: // Open another rep sl@0: repository2->OpenL(KUidCacheTestRepositorySm2,*notifier2); sl@0: sl@0: now.UniversalTime(); sl@0: TheTest.Printf(_L("KUidCacheTestRepositorySm2 added at %Ld\n"), now.MicroSecondsFrom(starttime).Int64()); sl@0: sl@0: // wait more than default timeout. sl@0: timer->Start(TTimeIntervalMicroSeconds32(TServerResources::iCacheManager->iDefaultTimeout.Int()+KTimerDelay), 0, TCallBack(Callback, timer)); sl@0: sl@0: CActiveScheduler::Start(); sl@0: sl@0: // Callback should have been called by now sl@0: count = TServerResources::iCacheManager->iIdleRepositories.Count(); sl@0: if (count > 0) sl@0: { sl@0: // Do not fail test on emulator. CTimer::AtUTC is often sl@0: // late by 1 to a few seconds. sl@0: #if defined(__WINSCW__) || defined(__WINS__) sl@0: TheTest.Printf(_L("*** Line %d check fail. Ignored on winscw."), __LINE__); sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: #endif sl@0: } sl@0: sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: sl@0: repository2->Close(); sl@0: repository->Close(); sl@0: sl@0: CleanupStack::PopAndDestroy(repository2); sl@0: CleanupStack::PopAndDestroy(notifier2); sl@0: CleanupStack::PopAndDestroy(repository); sl@0: CleanupStack::PopAndDestroy(notifier); sl@0: sl@0: CleanupStack::PopAndDestroy(timer); sl@0: } sl@0: sl@0: void TRepositoryCacheManagerTester::DefectTestsL() sl@0: { sl@0: iTestStepStage = 3; // Don't run OOM tests on defects sl@0: sl@0: NextTest(_L( "DEF093491: [AQP]Centrep server flushes repository cache when temporarily disabled" )); sl@0: DEF093491L(); sl@0: sl@0: NextTest(_L( "INC105967: CenRep crashes when no ROM directory" )); sl@0: INC105967(); sl@0: sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-1883 sl@0: @SYMTestCaseDesc [AQP]Centrep server flushes repository cache when temporarily disabled sl@0: @SYMTestPriority High sl@0: @SYMTestActions Open repository, disable cache, check if the rep is still in memory sl@0: @SYMTestExpectedResults The test must not fail or panic . sl@0: @SYMDEF DEF093491 sl@0: */ sl@0: void TRepositoryCacheManagerTester::DEF093491L() sl@0: { sl@0: NextTest( _L( " @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-1883 " ) ); sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: sl@0: // Notifier needed to open repositories. sl@0: CSessionNotifier* notifier; sl@0: notifier = new(ELeave)CSessionNotifier; sl@0: CleanupStack::PushL(notifier); sl@0: sl@0: CServerRepository* repository = new(ELeave) CServerRepository(); sl@0: CleanupStack::PushL(repository); sl@0: // Open repository sl@0: repository->OpenL(KUidCacheTestRepositorySm,*notifier); sl@0: sl@0: // Check it's in cache and memory sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: TEST( TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) != KErrNotFound ); sl@0: // disable cache sl@0: TServerResources::iCacheManager->DisableCache(); sl@0: sl@0: // Check it's in memory but not in cache sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: TEST( TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) != KErrNotFound ); sl@0: sl@0: repository->Close(); sl@0: // the repository should now be unloaded from memory sl@0: TEST( TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) == KErrNotFound ); sl@0: // enable cache again sl@0: TServerResources::iCacheManager->EnableCache(); sl@0: sl@0: // Open repository again sl@0: repository->OpenL(KUidCacheTestRepositorySm,*notifier); sl@0: sl@0: // Check it's in cache and memory sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 1 ); sl@0: TEST( TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) != KErrNotFound ); sl@0: sl@0: repository->Close(); sl@0: sl@0: // disable cache sl@0: TServerResources::iCacheManager->DisableCache(ETrue); sl@0: sl@0: // now it should be flushed out of both memory and cache sl@0: TEST( TServerResources::iCacheManager->iIdleRepositories.Count() == 0 ); sl@0: TEST( TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) == KErrNotFound ); sl@0: sl@0: CleanupStack::PopAndDestroy(repository); sl@0: CleanupStack::PopAndDestroy(notifier); sl@0: } sl@0: sl@0: // Helper function for INC105967L sl@0: LOCAL_C TInt TestThread(TAny*) sl@0: { sl@0: CTrapCleanup* cleanup = CTrapCleanup::New(); sl@0: if(!cleanup) sl@0: return KErrNoMemory; sl@0: sl@0: HBufC* tempFileName; sl@0: // this call shouldn't cause a panic, but leave with KErrNotFound sl@0: TRAPD(err, sl@0: { sl@0: TServerResources::CreateRepositoryFileNameLC(tempFileName, KUidCacheTestRepositorySm, ERom, ECre); sl@0: CleanupStack::PopAndDestroy(tempFileName); sl@0: }); sl@0: // test if the function leaves with KErrNot Found sl@0: TEST2(err, KErrNotFound); sl@0: sl@0: delete cleanup; sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-CENTRALREPOSITORY-UT-3474 sl@0: @SYMTestCaseDesc CenRep crashes when no ROM directory sl@0: @SYMTestPriority High sl@0: @SYMTestActions Save RomDirectory, temporarily NULL the pointer, call panicking function in a seperate thread sl@0: (to survive even if it panics and continue other tests), check that it leaves with KErrNotFound, restore RomDirectory sl@0: @SYMTestExpectedResults The test must not panic. sl@0: @SYMDEF INC105967 sl@0: */ sl@0: void TRepositoryCacheManagerTester::INC105967() sl@0: { sl@0: NextTest( _L( " @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-UT-3474 " ) ); sl@0: //store RomDirectory sl@0: HBufC* tempRomDirectory = TServerResources::iRomDirectory; sl@0: sl@0: // temporarily delete it to simulate the behaviour in TServerResources::InitialiseL() when: sl@0: // if(iFs.Entry(*iRomDirectory, fsEntry)!=KErrNone || !fsEntry.IsDir()) sl@0: TServerResources::iRomDirectory = NULL; sl@0: sl@0: RThread testThread; sl@0: _LIT(KThreadName, "TestThread"); sl@0: sl@0: testThread.Create(KThreadName, TestThread, KDefaultStackSize, KMinHeapSize, 0x100000, NULL); sl@0: sl@0: TRequestStatus requestStatus; sl@0: // Request notification when the thread terminates sl@0: testThread.Logon(requestStatus); sl@0: // Let the thread execute sl@0: testThread.Resume(); sl@0: sl@0: // Wait for termination sl@0: User::WaitForRequest(requestStatus); sl@0: // test if the thread terminated normally (the leave has been trapped) not panicked sl@0: TEST2(requestStatus.Int(), KErrNone); sl@0: sl@0: //restore RomDirectory sl@0: TServerResources::iRomDirectory = tempRomDirectory; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID PDS-CENTRALREPOSITORY-UT-4077 sl@0: @SYMTestCaseDesc Central Repository cache manager incorrectly uses CTimer::AtUTC() sl@0: @SYMTestPriority High sl@0: @SYMTestActions Call CRepositoryCacheManager::RescheduleTimer passing in various sl@0: timer values to test conversion of 64 bit UTC time value into sl@0: 32 bit microsecond value. sl@0: @SYMTestExpectedResults The timer should be active after each call to RescheduleTimer sl@0: The test must not panic. sl@0: @SYMDEF DEF124147 sl@0: */ sl@0: void TRepositoryCacheManagerTester::DEF124147() sl@0: { sl@0: NextTest( _L( " @SYMTestCaseID:PDS-CENTRALREPOSITORY-UT-4077 " ) ); sl@0: sl@0: //Cancel any pending timer sl@0: TServerResources::iCacheManager->Cancel(); sl@0: sl@0: TTime now; sl@0: now.UniversalTime(); sl@0: sl@0: TTimeIntervalMinutes oneMinute(1); sl@0: TTimeIntervalHours oneHour(1); sl@0: sl@0: //Rechedule timer now sl@0: TServerResources::iCacheManager->RescheduleTimer(now); sl@0: TEST(TServerResources::iCacheManager->IsActive()); sl@0: sl@0: //Cancel any pending timer sl@0: TServerResources::iCacheManager->Cancel(); sl@0: sl@0: sl@0: //Rechedule timer in the past sl@0: TServerResources::iCacheManager->RescheduleTimer(now - oneMinute); sl@0: TEST(TServerResources::iCacheManager->IsActive()); sl@0: sl@0: //Cancel any pending timer sl@0: TServerResources::iCacheManager->Cancel(); sl@0: sl@0: //Rechedule timer in the future sl@0: TServerResources::iCacheManager->RescheduleTimer(now + oneMinute); sl@0: TEST(TServerResources::iCacheManager->IsActive()); sl@0: sl@0: //Cancel any pending timer sl@0: TServerResources::iCacheManager->Cancel(); sl@0: sl@0: //Rechedule timer an hour in the past sl@0: TServerResources::iCacheManager->RescheduleTimer(now - oneHour); sl@0: TEST(TServerResources::iCacheManager->IsActive()); sl@0: sl@0: //Cancel any pending timer sl@0: TServerResources::iCacheManager->Cancel(); sl@0: sl@0: //Rechedule timer an hour in the future sl@0: TServerResources::iCacheManager->RescheduleTimer(now + oneHour); sl@0: TEST(TServerResources::iCacheManager->IsActive()); sl@0: sl@0: //Cancel any pending timer sl@0: TServerResources::iCacheManager->Cancel(); sl@0: } sl@0: sl@0: // --------------------------------------------------- sl@0: // OomTest sl@0: // sl@0: // Function to convert a test into an OOM test sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-1422 sl@0: @SYMTestCaseDesc Test functionality under OOM. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Test functionality under OOM. sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMPREQ PREQ1192 sl@0: @SYMTestStatus Defined sl@0: @SYMDevelopedForRelease Symbian OS v9.3 sl@0: @SYMAuthor Aleks Pamir sl@0: */ sl@0: LOCAL_C void OomTest( void (*testFuncL)() ) sl@0: { sl@0: TheTest.Next( _L( " @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-1422 " ) ); sl@0: TInt error; sl@0: TInt count = 0; sl@0: sl@0: do sl@0: { sl@0: User::__DbgMarkStart( RHeap::EUser ); sl@0: sl@0: // find out the number of open handles sl@0: TInt startProcessHandleCount; sl@0: TInt startThreadHandleCount; sl@0: RThread().HandleCount(startProcessHandleCount, startThreadHandleCount); sl@0: sl@0: User::__DbgSetAllocFail( RHeap::EUser, RHeap::EFailNext, ++count ); sl@0: sl@0: TRAP( error, (testFuncL)() ); sl@0: sl@0: User::__DbgSetAllocFail( RHeap::EUser, RHeap::ENone, 1 ); sl@0: sl@0: // check that no handles have leaked sl@0: TInt endProcessHandleCount; sl@0: TInt endThreadHandleCount; sl@0: RThread().HandleCount(endProcessHandleCount, endThreadHandleCount); sl@0: sl@0: TEST(startProcessHandleCount == endProcessHandleCount); sl@0: TEST(startThreadHandleCount == endThreadHandleCount); sl@0: sl@0: User::__DbgMarkEnd( RHeap::EUser, 0 ); sl@0: } while( error == KErrNoMemory ); sl@0: sl@0: _LIT( KTestFailed, "Out of memory test failure on iteration %d\n" ); sl@0: __ASSERT_ALWAYS( error == KErrNone, TheTest.Panic( error, KTestFailed, count ) ); sl@0: sl@0: TheTest.Printf( _L( "Out of memory tests succeeded at heap failure rate of %i\n" ), count ); sl@0: TheTest.Printf( _L( "Process handle count preserved\n" ) ); sl@0: TheTest.Printf( _L( "Thread handle count preserved\n" ) ); sl@0: } sl@0: sl@0: LOCAL_C void DoOOMTestsL() sl@0: { sl@0: // To clean up the static array under OOM sl@0: CleanupStack::PushL(gCleanup); sl@0: sl@0: // To be able to run tests faster, especially the last 2 tests with delays, sl@0: // a flow-through to the next case statement is intended here. If the Tester sl@0: // function completes successfully, meaning that it has passed all memory sl@0: // allocations, then the execution continues from the next step and the iTestStepStage sl@0: // variable is set to the current test step stage. Otherwise the function will Leave sl@0: // with KErrNoMemory, will be trapped in OomTest and DoOOMTestsL will be recalled. sl@0: // Once a test step stage is passed, Tester.iTestStepStage will ensure that the same sl@0: // function will no be called over and over again for every memory allocation failure, sl@0: // thereby reducing the running time of the test considerably. sl@0: sl@0: switch(Tester.iTestStepStage) sl@0: { sl@0: case 0: sl@0: { sl@0: Tester.FuncTestsL(); sl@0: } sl@0: case 1: sl@0: { sl@0: Tester.SizeTestsL(); sl@0: } sl@0: case 2: sl@0: { sl@0: Tester.TimingTestsL(); sl@0: } sl@0: default: sl@0: break; sl@0: } sl@0: // To clean up the memory left in static variables sl@0: Tester.CleanUp(NULL); sl@0: sl@0: CleanupStack::Pop(); sl@0: } sl@0: sl@0: LOCAL_C void DoTestsL() sl@0: { sl@0: switch(Tester.iStage) sl@0: { sl@0: case ENominalNoFile: sl@0: default: sl@0: { sl@0: TheTest.Start( _L( "Cache functionality tests with default params(no .ini)" ) ); sl@0: Tester.FuncTestsL(); sl@0: Tester.SizeTestsL(); sl@0: Tester.TimingTestsL(); sl@0: TheTest.End(); sl@0: break; sl@0: } sl@0: case ENominal: sl@0: { sl@0: TheTest.Start( _L( "Cache functionality tests with default params(default values read from .ini)" ) ); sl@0: Tester.FuncTestsL(); sl@0: Tester.SizeTestsL(); sl@0: Tester.TimingTestsL(); sl@0: // Only test defects once here unless a defect occurs in different memory conditions sl@0: Tester.DefectTestsL(); sl@0: TheTest.End(); sl@0: break; sl@0: } sl@0: case ESizeMin: sl@0: { sl@0: TheTest.Start( _L( "Cache functionality tests with no space for cache (size=0)" ) ); sl@0: Tester.FuncTestsL(); sl@0: // No size tests because size is controlled in this test sl@0: // No Timing tests because nothing will be cached(cache size 0) so nothing to time sl@0: TheTest.End(); sl@0: break; sl@0: } sl@0: case ESizeMinplus: sl@0: { sl@0: TheTest.Start( _L( "Cache functionality tests with small cache size" ) ); sl@0: Tester.FuncTestsL(); sl@0: // No size tests because size is controlled in this test sl@0: Tester.TimingTestsL(); sl@0: TheTest.End(); sl@0: break; sl@0: } sl@0: case ESizeMaxminus: sl@0: { sl@0: TheTest.Start( _L( "Cache functionality tests with large cache size" ) ); sl@0: Tester.FuncTestsL(); sl@0: // No size tests because size is controlled in this test sl@0: Tester.TimingTestsL(); sl@0: TheTest.End(); sl@0: break; sl@0: } sl@0: case ESizeMax: sl@0: { sl@0: TheTest.Start( _L( "Cache functionality tests with max cache size (=heap max 2MB)" ) ); sl@0: Tester.FuncTestsL(); sl@0: // No size tests because size is controlled in this test sl@0: Tester.TimingTestsL(); sl@0: TheTest.End(); sl@0: break; sl@0: } sl@0: case ESizeMaxplus: sl@0: { sl@0: TheTest.Start( _L( "Cache functionality Robustness test" ) ); sl@0: Tester.FuncTestsL(); sl@0: // No size tests because size is controlled in this test sl@0: Tester.TimingTestsL(); sl@0: TheTest.End(); sl@0: break; sl@0: } sl@0: case ETimeoutMin: sl@0: { sl@0: TheTest.Start( _L( "Cache functionality tests with no timeout for cache (timeout=0)" ) ); sl@0: Tester.FuncTestsL(); sl@0: Tester.SizeTestsL(); sl@0: // No timing tests because timeout is controlled in this test sl@0: TheTest.End(); sl@0: break; sl@0: } sl@0: case ETimeoutMinplus: sl@0: { sl@0: TheTest.Start( _L( "Cache functionality tests with short timeout" ) ); sl@0: Tester.FuncTestsL(); sl@0: Tester.SizeTestsL(); sl@0: // No timing tests because timeout is controlled in this test sl@0: TheTest.End(); sl@0: break; sl@0: } sl@0: case ETimeoutMaxminus: sl@0: { sl@0: TheTest.Start( _L( "Cache functionality tests with large timeout" ) ); sl@0: Tester.FuncTestsL(); sl@0: Tester.SizeTestsL(); sl@0: // No timing tests because timeout is controlled in this test sl@0: TheTest.End(); sl@0: break; sl@0: } sl@0: case EReallyWorstCase: sl@0: { sl@0: TheTest.Start( _L( "Cache functionality Worst Case test with no timeout and no size for cache" ) ); sl@0: Tester.FuncTestsL(); sl@0: Tester.SizeTestsL(); sl@0: // No Timing tests because nothing will be cached(cache size 0) so nothing to time sl@0: TheTest.End(); sl@0: break; sl@0: } sl@0: }; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-CENTRALREPOSITORY-UT-4014 sl@0: @SYMTestCaseDesc Cenrep cache manager should not evict sub-sessions in active transactions. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Open 2 sub-sessions to a repository, start a transaction, let the cache manager run. sl@0: @SYMTestExpectedResults The test must not fail or panic . sl@0: @SYMDEF DEF111734 sl@0: */ sl@0: void TRepositoryCacheManagerTester::DEF111734L() sl@0: { sl@0: NextTest( _L( " @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-UT-4014 DEF111734: Cache Manager and Open Transactions ")); sl@0: sl@0: TServerResources::iCacheManager->FlushCache(); sl@0: sl@0: // Notifier needed to open repositories. sl@0: // notifier 1 sl@0: CSessionNotifier* notifier; sl@0: notifier = new(ELeave)CSessionNotifier; sl@0: CleanupStack::PushL(notifier); sl@0: sl@0: // notifier 2 sl@0: CSessionNotifier* notifier2; sl@0: notifier2 = new(ELeave)CSessionNotifier; sl@0: CleanupStack::PushL(notifier2); sl@0: sl@0: // connection 1 sl@0: CServerRepository* repository = new(ELeave) CServerRepository(); sl@0: CleanupStack::PushL(repository); sl@0: sl@0: // connection 2 sl@0: CServerRepository* repository2 = new(ELeave) CServerRepository(); sl@0: CleanupStack::PushL(repository2); sl@0: sl@0: // Open repository sl@0: repository->OpenL(KUidCacheTestRepositorySm,*notifier); sl@0: sl@0: // open second connection to the repository sl@0: repository2->OpenL(KUidCacheTestRepositorySm,*notifier2); sl@0: sl@0: // we have to observers to the same repository - so we should have only 1 entry in sl@0: // the idle repositories for the cache manager sl@0: sl@0: TEST(TServerResources::iCacheManager->iIdleRepositories.Count() == 1); sl@0: sl@0: // check CR's global memory for an instance for this repository. sl@0: TEST(TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) != KErrNotFound); sl@0: sl@0: // start a transaction on connection 2, this adds this sub-session to the sl@0: // transaction queue for the repository. sl@0: sl@0: TInt error = repository2->StartTransaction(3); sl@0: TEST(error == KErrNone); sl@0: sl@0: // This will wipe out the memory for the open repository unless we modify the code in some fashion. sl@0: TServerResources::iCacheManager->FlushCache(EFalse); sl@0: sl@0: // since we can't use the user::after method since we need to this thread to suspend sl@0: // start a timer (stolen from above). sl@0: CPeriodic* timer = CPeriodic::NewL(EPriorityLow); sl@0: CleanupStack::PushL(timer); sl@0: sl@0: sl@0: // since repositories that involved in active transactions no longer have their memory sl@0: // removed by cache manager, give this time enough time to go through a few cycles of sl@0: // the normal eviction process. sl@0: sl@0: timer->Start(TTimeIntervalMicroSeconds32(TServerResources::iCacheManager->iDefaultTimeout.Int()*3), 0, TCallBack(Callback, timer)); sl@0: sl@0: // will cause the cache manager to run sl@0: CActiveScheduler::Start(); sl@0: sl@0: // If it isn't in cache and memory than the cache manager must have collected it sl@0: // and the code for this defect is not in the build. sl@0: TEST(TServerResources::iCacheManager->iIdleRepositories.Count() == 0); sl@0: TEST(TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) != KErrNotFound); sl@0: sl@0: // close this sub-session. should cancel the active transaction. allowing cache manager to clean sl@0: // up the memory. sl@0: repository2->Close(); sl@0: sl@0: TInt i = 0; sl@0: const TUint32 KInt1 = 0x1; sl@0: repository->Get(KInt1, i); sl@0: sl@0: // close the last observer for this repository. this places the memory for this repository sl@0: // back onto the idle list for cache manager. sl@0: repository->Close(); sl@0: sl@0: // Wait until the repository is evicted normally sl@0: sl@0: timer->Start(TTimeIntervalMicroSeconds32(TServerResources::iCacheManager->iDefaultTimeout.Int()*2), 0, TCallBack(Callback, timer)); sl@0: sl@0: CActiveScheduler::Start(); sl@0: sl@0: // the repository should now be unloaded from memory sl@0: TEST( TServerResources::iObserver->FindOpenRepository(KUidCacheTestRepositorySm) == KErrNotFound ); sl@0: sl@0: CleanupStack::PopAndDestroy(5); sl@0: } sl@0: sl@0: LOCAL_C void MainL() sl@0: { sl@0: __UHEAP_MARK; sl@0: TheTest.Start( _L( "Cache Tests" ) ); sl@0: sl@0: // create and install the active scheduler we need sl@0: CActiveScheduler* s = new(ELeave) CActiveScheduler; sl@0: CleanupStack::PushL( s ); sl@0: CActiveScheduler::Install( s ); sl@0: sl@0: Tester.DeleteFilesL(); sl@0: sl@0: TServerResources::InitialiseL(); sl@0: sl@0: sl@0: Tester.DEF111734L(); sl@0: Tester.DEF124147(); sl@0: sl@0: sl@0: for(TInt i=ENominalNoFile; i(i) ); sl@0: DoTestsL(); sl@0: } sl@0: sl@0: TheTest.Next( _L( "Out of memory tests" ) ); sl@0: Tester.iOOMTest = ETrue; sl@0: sl@0: Tester.AdvanceToStageL( ENominal ); sl@0: OomTest( DoOOMTestsL ); sl@0: sl@0: TServerResources::Close(); sl@0: sl@0: // Cleanup the scheduler sl@0: CleanupStack::PopAndDestroy( s ); sl@0: sl@0: TheTest.End(); sl@0: TheTest.Close(); sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: TInt E32Main() sl@0: { sl@0: #ifdef __SECURE_DATA__ sl@0: __UHEAP_MARK; sl@0: CTrapCleanup* cleanup = CTrapCleanup::New(); sl@0: if ( !cleanup ) sl@0: return KErrNoMemory; sl@0: sl@0: TRAPD( err, MainL() ); sl@0: if ( err != KErrNone ) sl@0: User::Panic( _L( "Testing failed: " ), err ); sl@0: sl@0: delete cleanup; sl@0: __UHEAP_MARKEND; sl@0: #endif sl@0: sl@0: return 0; sl@0: } sl@0: