lowlevellibsandfws/pluginfw/Framework/ResolverTest/t_resolvercache.cpp
changeset 31 ce057bb09d0b
child 45 4b03adbd26ca
equal deleted inserted replaced
30:e20de85af2ee 31:ce057bb09d0b
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // This file contains test classes and their implementations
       
    15 // to test production class CCustomResolverCache.
       
    16 // 
       
    17 //
       
    18 
       
    19 #include <e32test.h>
       
    20 #include <f32file.h>
       
    21 #include <hal.h>
       
    22 #include <bautils.h>
       
    23 #include <babitflags.h>
       
    24 #include <babackup.h>
       
    25 #include <startup.hrh>
       
    26 #include <ecom/resolver.h>
       
    27 #include "EComErrorCodes.h"
       
    28 #include "EComUidCodes.h"
       
    29 #include "ImplementationInformation.h"
       
    30 #include "RegistryData.h"
       
    31 #include "Registrar.h"
       
    32 #include "RegistrarObserver.h"
       
    33 #include "../EcomTestUtils/EcomTestUtils.h"
       
    34 #include <swi/swispubsubdefs.h>
       
    35 #include "../EcomTestUtils/TPropertyManager.h"
       
    36 #include "EComPatchDataConstantv2.h"
       
    37 #include "RegistryResolveTransaction.h"  // ecom3 code
       
    38 #include "callback.h"
       
    39 #include "resolvercache.h"
       
    40 #include "EComServer.h"
       
    41 
       
    42 
       
    43 const TInt KOneSecond = 1000000;
       
    44 const TInt KHalfSecond = KOneSecond / 2;
       
    45 // Use this timeout to wait for events occuring within a few seconds.
       
    46 const TInt KIndefiniteWait = KOneSecond * 20;
       
    47 
       
    48 LOCAL_D RTest test(_L("t_resolvercache.exe"));
       
    49 
       
    50 LOCAL_D RFs					TheFs;
       
    51 LOCAL_D CTrapCleanup* 		TheTrapCleanup 		= NULL;
       
    52 class CDerivedActiveScheduler;
       
    53 LOCAL_D CDerivedActiveScheduler* TheActiveScheduler	= NULL;
       
    54 
       
    55 
       
    56 // custom resolvers available for testing.
       
    57 // 200126cd, A0001346 and A0001347 are allocated outside the
       
    58 // ECOM Uid Allocations.doc
       
    59 const TUid KDummyResolverUid2  = {0xA0001346};
       
    60 const TUid KDummyResolverUid3  = {0xA0001347};
       
    61 const TUid KExampleResolverUid = {0x10009DD0};
       
    62 const TUid KMyResolverUid      = {0x10009E12};
       
    63 const TUid KDummyResolverUid1  = {0x200126CD};
       
    64 
       
    65 // The custom resolver in RAMOnly dir
       
    66 _LIT(KDummyRscInC, "c:\\resource\\plugins\\dummycustomresolver1.rsc");
       
    67 _LIT(KDummyDllInC, "c:\\sys\\bin\\dummycustomresolver1.dll");
       
    68 
       
    69 _LIT(KDummyRscInZ, "z:\\ramonly\\dummycustomresolver1.rsc");
       
    70 _LIT(KDummyDllInZ, "z:\\ramonly\\dummycustomresolver1.dll");
       
    71 
       
    72 // This pair is to upgrade a resolver DLL.
       
    73 // NB: to supersede a Z: drive plugin, the C: DLL must have the
       
    74 // same name as the one in z: drive. Hence the '2' is dropped.
       
    75 _LIT(KDllUpgradeInZ, "z:\\ramonly\\cachedcustomresolver2.dll");
       
    76 _LIT(KDllUpgradeInC, "c:\\sys\\bin\\cachedcustomresolver.dll");
       
    77 
       
    78 _LIT(KRscUpgradeInZ, "z:\\ramonly\\cachedcustomresolver2.rsc");
       
    79 _LIT(KRscUpgradeInC, "c:\\resource\\plugins\\cachedcustomresolver.rsc");
       
    80 
       
    81 /** User::AfterHighRes is not a reliable mechanism to wait
       
    82 for async events. Especially when we have 4 different timers
       
    83 firing within a span of 4 s. Hence this harness intercepts
       
    84 and inserts callbacks in the notification sources and set
       
    85 the following flag to indicate what event has occured. */
       
    86 LOCAL_D TBitFlags32 AsyncEvents = 0;
       
    87 
       
    88 /** enum to identify different async events */
       
    89 enum TAsyncEventId
       
    90 	{
       
    91 	EAsyncEvent_Unknown = 0,
       
    92 	EAsyncEvent_ImplUpgrade,
       
    93 	EAsyncEvent_SwiStart,
       
    94 	EAsyncEvent_SwiEnd,
       
    95 	EAsyncEvent_BurStart,
       
    96 	EAsyncEvent_BurEnd,
       
    97 	EAsyncEvent_CacheTimer,
       
    98 	EAsyncEvent_HaltTimer
       
    99 	};
       
   100 
       
   101 //
       
   102 // maps callback data to enum TAsyncEventId.
       
   103 LOCAL_C TAsyncEventId CallbackDataToEventId(TInt aEvent, TAny* aData)
       
   104 	{
       
   105 	TAsyncEventId ret = EAsyncEvent_Unknown;
       
   106 	TCallBackState* state = static_cast<TCallBackState*>(aData);
       
   107 	if (aEvent == ECallBackId_SwiEvent)
       
   108 		{
       
   109 		if (*state == ECallBackState_EventStart)
       
   110 			{
       
   111 			ret = EAsyncEvent_SwiStart;
       
   112 			}
       
   113 		else // treat all unexpected states as SWI end!
       
   114 			{
       
   115 			ret = EAsyncEvent_SwiEnd;
       
   116 			}
       
   117 		}
       
   118 	else if (aEvent == ECallBackId_BurEvent)
       
   119 		{
       
   120 		if (*state == ECallBackState_EventStart)
       
   121 			{
       
   122 			ret = EAsyncEvent_BurStart;
       
   123 			}
       
   124 		else // treat all unexpected states as BUR finish!
       
   125 			{
       
   126 			ret = EAsyncEvent_BurEnd;
       
   127 			}
       
   128 		}
       
   129 	else if (aEvent == ECallBackId_ImplUpgrade)
       
   130 		{
       
   131 		ret = EAsyncEvent_ImplUpgrade;
       
   132 		}
       
   133 	return ret;
       
   134 	}
       
   135 
       
   136 // beginningOfTest is set when this harness is run.
       
   137 LOCAL_D TTime beginningOfTest;
       
   138 LOCAL_C void WaitForLazyUnloadingL()
       
   139 	{
       
   140 	TTime now;
       
   141 	now.UniversalTime();
       
   142 
       
   143 	TTimeIntervalSeconds n;
       
   144 	User::LeaveIfError(now.SecondsFrom(beginningOfTest, n));
       
   145 	const TInt KLazyDllUnloadPeriod =  150; // actual is 2 minutes
       
   146 	TInt secondsToWait = KLazyDllUnloadPeriod - n.Int();
       
   147 	test.Printf(_L("Amount to wait for lazy unload is %d seconds.\n"), secondsToWait);
       
   148 	if (secondsToWait > 0)
       
   149 		{
       
   150 		User::After(KOneSecond * secondsToWait);
       
   151 		}
       
   152 	}
       
   153 
       
   154 // Copies the Plugins to specific folder for testing purpose
       
   155 LOCAL_C void CopyPluginsL()
       
   156 	{
       
   157 	EComTestUtils::FileManCopyFileL(KDummyRscInZ, KDummyRscInC);
       
   158 	EComTestUtils::FileManCopyFileL(KDummyDllInZ, KDummyDllInC);
       
   159 	}
       
   160 
       
   161 // Deleting plugin from the RAM for cleanup purpose
       
   162 LOCAL_C void DeleteTestPlugin()
       
   163 	{
       
   164 	TRAP_IGNORE(EComTestUtils::FileManDeleteFileL(KDummyRscInC));
       
   165 	TRAP_IGNORE(EComTestUtils::FileManDeleteFileL(KDummyDllInC));
       
   166 
       
   167 	TRAP_IGNORE(EComTestUtils::FileManDeleteFileL(KRscUpgradeInC));
       
   168 	TRAP_IGNORE(EComTestUtils::FileManDeleteFileL(KDllUpgradeInC));
       
   169 	}
       
   170 
       
   171 // utility to help cast TTimeIntervalMicroSeconds to TInt
       
   172 LOCAL_C TInt CalcElapsedMicroseconds(const TTime& aStart)
       
   173 	{
       
   174 	TTime now;
       
   175 	now.UniversalTime();
       
   176 	TTimeIntervalMicroSeconds timediff = now.MicroSecondsFrom(aStart);
       
   177 	return I64LOW( timediff.Int64() );
       
   178 	}
       
   179 
       
   180 /** Need a CActive to wait for various change notifications. */
       
   181 class CHaltTimer : public CTimer
       
   182 	{
       
   183 public:
       
   184 	CHaltTimer(TInt aPriority);
       
   185 	~CHaltTimer();
       
   186 	void ConstructL();
       
   187 	void StartTimer(TInt aTimeInterval);
       
   188 
       
   189 private:
       
   190 	void RunL();
       
   191 	};
       
   192 
       
   193 CHaltTimer::CHaltTimer(TInt aPriority)
       
   194 	: CTimer(aPriority)
       
   195 	{
       
   196 	CActiveScheduler::Add(this);
       
   197 	}
       
   198 
       
   199 CHaltTimer::~CHaltTimer()
       
   200 	{
       
   201 	Cancel();
       
   202 	}
       
   203 
       
   204 void CHaltTimer::ConstructL()
       
   205 	{
       
   206 	CTimer::ConstructL();
       
   207 	}
       
   208 
       
   209 void CHaltTimer::StartTimer(TInt aTimeInterval)
       
   210 	{
       
   211 	After(aTimeInterval);
       
   212 	}
       
   213 
       
   214 void CHaltTimer::RunL()
       
   215 	{
       
   216 	AsyncEvents.Set(EAsyncEvent_HaltTimer);
       
   217 	CActiveScheduler::Stop();
       
   218 	}
       
   219 
       
   220 /** Avoid E32User::Case 47 panic in OOM test */
       
   221 class CDerivedActiveScheduler : public CActiveScheduler
       
   222 	{
       
   223 public:
       
   224 	virtual void Error(TInt aError) const;
       
   225 	};
       
   226 
       
   227 void CDerivedActiveScheduler::Error(TInt aError) const
       
   228 	{
       
   229 	Halt(aError);
       
   230 	}
       
   231 
       
   232 /** friend class to access private members of CEComServer */
       
   233 class TEComServer_StateAccessor
       
   234 	{
       
   235 public:
       
   236 	static void InterceptCallbacks(CEComServer& aEComServer, TCallBackWithArg aCb);
       
   237 	static CCustomResolverCache* GetResolverCache(CEComServer& aEComServer);
       
   238 	};
       
   239 
       
   240 /** Test class for object CCustomResolverCache.
       
   241 */
       
   242 class CCustomResolverCacheTest : public CBase
       
   243 	{
       
   244 public:
       
   245 	typedef void (CCustomResolverCacheTest::*ClassFuncPtrL) (void);
       
   246 
       
   247 	virtual ~CCustomResolverCacheTest();
       
   248 	static CCustomResolverCacheTest* NewL();
       
   249 	static void RunAllTestsL();
       
   250 	static TInt InterceptCacheMgrCallback(TAny* aObj, TInt aEvent, TAny* aData);
       
   251 	static TInt CacheTimeoutCallback(TAny* aObj, TInt aEvent, TAny* aData);
       
   252 
       
   253 private:
       
   254 	CCustomResolverCacheTest();
       
   255 	void ConstructL();
       
   256 
       
   257 	static void DoBasicTestL(ClassFuncPtrL aTestFunc);
       
   258 	static void DoOOMTestL(ClassFuncPtrL aTestFunc);
       
   259 
       
   260 	// Test cases
       
   261 	void TestUpgradingCachedResolverL();
       
   262 	void TestDeletingCachedResolverL();
       
   263 
       
   264 	void TestCacheQueueFullPattern1L();
       
   265 	void TestCacheQueueFullPattern2L();
       
   266 	void TestCacheQueueFullPattern3L();
       
   267 	void DoQueueFullTestL(const RArray<TUid>& aResolverList);
       
   268 
       
   269 	void TestCounterWrapAroundL();
       
   270 	void TestCacheTimerAccuracyL();
       
   271 	void TestTimestampUpdateOnCacheHitL();
       
   272 	void TestSWIDisableRwResolverCachingL();
       
   273 	void TestBurDisableRwResolverCachingL();
       
   274 	void TestClockChangeHasNoEffectOnCacheTimeoutL();
       
   275 	void TestCacheSizeZeroL();
       
   276 	void TestCacheTimeoutZeroL();
       
   277 	void TestResolverWithBadProxyTable();
       
   278 
       
   279 	// utilities
       
   280 	TBool UseResolverCheckVersionL(TUid aResolverUid,
       
   281 								   TInt aVersion = 0);
       
   282 	void YieldToOtherCActive(TInt aMicroSeconds);
       
   283 	void WaitAsyncL(TInt aNumSeconds);
       
   284 	TBool WaitForEvict(TUid aResolverUid);
       
   285 
       
   286 	// access private data of CCustomResolverCache
       
   287 	TInt CacheSize();
       
   288 	TBool HasResolverUid(TUid aUid);
       
   289 	TBool QueueIsSorted();
       
   290 	inline CCustomResolverCache* ResolverCache();
       
   291 
       
   292 private:
       
   293 	/** need a CActive to wait for other async events */
       
   294 	CHaltTimer* iHaltTimer;
       
   295 
       
   296 	CEComServer* iEComServer;
       
   297 	};
       
   298 
       
   299 //==============================================
       
   300 // class TEComServer_StateAccessor
       
   301 //==============================================
       
   302 void TEComServer_StateAccessor::InterceptCallbacks(CEComServer& aEComServer,
       
   303 												   TCallBackWithArg aCb)
       
   304 	{
       
   305 	aEComServer.iRegistrar->InstallSwiEventCallBack(aCb);
       
   306 	aEComServer.iRegistrar->InstallBurEventCallBack(aCb);
       
   307 	aEComServer.iRegistryData->SetImplUpgradeCallBack(aCb);
       
   308 	}
       
   309 
       
   310 CCustomResolverCache*
       
   311 TEComServer_StateAccessor::GetResolverCache(CEComServer& aEComServer)
       
   312 	{
       
   313 	return aEComServer.iResolverCache;
       
   314 	}
       
   315 
       
   316 //==============================================
       
   317 // class CCustomResolverCacheTest
       
   318 //==============================================
       
   319 
       
   320 /** CCustomResolverCacheTest constructor */
       
   321 CCustomResolverCacheTest::CCustomResolverCacheTest()
       
   322 	{
       
   323 	}
       
   324 
       
   325 /** CCustomResolverCacheTest destructor. */
       
   326 CCustomResolverCacheTest::~CCustomResolverCacheTest()
       
   327 	{
       
   328 	delete iEComServer;
       
   329 	delete iHaltTimer;
       
   330 	}
       
   331 
       
   332 /** static factory method to instantiate CCustomResolverCacheTest object.
       
   333 */
       
   334 CCustomResolverCacheTest* CCustomResolverCacheTest::NewL()
       
   335 	{
       
   336 	CCustomResolverCacheTest* self = new(ELeave) CCustomResolverCacheTest;
       
   337 	CleanupStack::PushL(self);
       
   338 	self->ConstructL();
       
   339 	CleanupStack::Pop(self);
       
   340 	return self;
       
   341 	}
       
   342 
       
   343 /**
       
   344 Standardized 2nd phase of two phase construction.
       
   345 */
       
   346 void CCustomResolverCacheTest::ConstructL()
       
   347 	{
       
   348 	iHaltTimer = new(ELeave) CHaltTimer(CActive::EPriorityIdle);
       
   349 	iHaltTimer->ConstructL();
       
   350 
       
   351 	iEComServer = CEComServer::NewLC();
       
   352 	CleanupStack::Pop(iEComServer);
       
   353 
       
   354 	TCallBackWithArg interceptorCB(&InterceptCacheMgrCallback, this);
       
   355 	TEComServer_StateAccessor::InterceptCallbacks(*iEComServer, interceptorCB);
       
   356 
       
   357 	TCallBackWithArg cacheTimerCb(&CacheTimeoutCallback, this);
       
   358 	ResolverCache()->iTimerExpireCB = cacheTimerCb;
       
   359 	}
       
   360 
       
   361 /** util to fetch CEComServer::iResolverCache */
       
   362 inline CCustomResolverCache* CCustomResolverCacheTest::ResolverCache()
       
   363 	{
       
   364 	return TEComServer_StateAccessor::GetResolverCache(*iEComServer);
       
   365 	}
       
   366 
       
   367 /** the test harness install this callback with ECOM server objects
       
   368 to intercept async events. This callback will relay the original
       
   369 call to CEComServer, then raise a flag to indicate what
       
   370 event has occurred.
       
   371 @param aObj pointer to the CCustomResolverCacheTest object
       
   372 @param aEvent ID of event triggering the callback
       
   373 @param aData  pointer to some data associated with the event.
       
   374 @return Always KErrNone. It is ignored.
       
   375 */
       
   376 TInt CCustomResolverCacheTest::InterceptCacheMgrCallback(TAny* aObj,
       
   377 														 TInt aEvent,
       
   378 														 TAny* aData)
       
   379 	{
       
   380 	CCustomResolverCacheTest* self = static_cast<CCustomResolverCacheTest*>(aObj);
       
   381 	// Pass the event along to let CEComServer does its thing.
       
   382 	CEComServer::NotifyEvents(self->iEComServer, aEvent, aData);
       
   383 
       
   384 	if (self->iHaltTimer->IsActive())
       
   385 		{
       
   386 		TAsyncEventId event = CallbackDataToEventId(aEvent, aData);
       
   387 		AsyncEvents.Set(event);
       
   388 
       
   389 		self->iHaltTimer->Cancel();
       
   390 		CActiveScheduler::Stop();
       
   391 		}
       
   392 	else
       
   393 		{
       
   394 		// BUR and SWI unit test cases just call the notifier
       
   395 		// directly. So CHaltTimer is not running.
       
   396 		test.Printf(_L("CacheTest: caught async event %d when timer not running\n"), aEvent);
       
   397 		}
       
   398 	return KErrNone;
       
   399 	}
       
   400 
       
   401 /** A callback installed in cache mgr. Whenever the cache timer expires
       
   402 this callback is invoked by CCustomResolverCache
       
   403 @param aObj pointer to CCustomResolverCacheTest
       
   404 @return Always KErrNone. It is ignored.
       
   405 */
       
   406 TInt CCustomResolverCacheTest::CacheTimeoutCallback(TAny* aObj, TInt, TAny*)
       
   407 	{
       
   408 	AsyncEvents.Set(EAsyncEvent_CacheTimer);
       
   409 
       
   410 	CCustomResolverCacheTest* self = static_cast<CCustomResolverCacheTest*>(aObj);
       
   411 	self->iHaltTimer->Cancel();
       
   412 	CActiveScheduler::Stop();
       
   413 	return KErrNone;
       
   414 	}
       
   415 
       
   416 /** Wrapper function to run normal mode (non-OOM) test
       
   417 */
       
   418 void CCustomResolverCacheTest::DoBasicTestL(ClassFuncPtrL aTestFunc)
       
   419 	{
       
   420 	__UHEAP_MARK;
       
   421 	TInt startProcessHandleCount;
       
   422 	TInt startThreadHandleCount;
       
   423 	RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);
       
   424 
       
   425 	CCustomResolverCacheTest* p = CCustomResolverCacheTest::NewL();
       
   426 	(p->*aTestFunc)();
       
   427 	delete p;
       
   428 
       
   429 	// check that no handles have leaked
       
   430 	TInt endProcessHandleCount;
       
   431 	TInt endThreadHandleCount;
       
   432 	RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);
       
   433 
       
   434 	test(startProcessHandleCount == endProcessHandleCount);
       
   435 	test(startThreadHandleCount  == endThreadHandleCount);
       
   436 	__UHEAP_MARKEND;
       
   437 	}
       
   438 
       
   439 /**
       
   440 @SYMTestCaseID		SYSLIB-ECOM-UT-4020
       
   441 @SYMTestCaseDesc 	Verify no memory leak in CCustomResolverCache.
       
   442 @SYMTestPriority 	Critical
       
   443 @SYMTestActions  	Run UT-4015, UT-4016 and UT-4017 under OOM.
       
   444 @SYMTestExpectedResults No memory leak, no handle leak.
       
   445 @SYMCR CR1182
       
   446 */
       
   447 void CCustomResolverCacheTest::DoOOMTestL(ClassFuncPtrL aTestFunc)
       
   448 	{
       
   449 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4020 "));
       
   450 	__UHEAP_MARK;
       
   451 	TInt startProcessHandleCount;
       
   452 	TInt startThreadHandleCount;
       
   453 	RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);
       
   454 	TInt err(KErrNone);
       
   455 	TInt oomStep = 0;
       
   456 
       
   457 	do {
       
   458 		// Instantiation of CCustomResolverCacheTest involves building
       
   459 		// the registry. It will take couple hours under OOM. Hence do it
       
   460 		// outside __UHEAP_SETFAIL.
       
   461 		CCustomResolverCacheTest* p = CCustomResolverCacheTest::NewL();
       
   462 
       
   463 		__UHEAP_SETFAIL(RHeap::EDeterministic, ++oomStep);
       
   464 		TRAP(err, (p->*aTestFunc)());
       
   465 		__UHEAP_SETFAIL(RHeap::ENone, 0);
       
   466 
       
   467 		delete p;
       
   468 	} while (err == KErrNoMemory);
       
   469 
       
   470 	test(err == KErrNone);
       
   471 	test.Printf(_L("OOM succeeded at heap failure rate %d\n"), oomStep);
       
   472 
       
   473 	// check that no handles have leaked
       
   474 	TInt endProcessHandleCount;
       
   475 	TInt endThreadHandleCount;
       
   476 	RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);
       
   477 
       
   478 	test(startProcessHandleCount == endProcessHandleCount);
       
   479 	test(startThreadHandleCount  == endThreadHandleCount);
       
   480 	__UHEAP_MARKEND;
       
   481 	}
       
   482 
       
   483 /** helper, ecom3 code
       
   484 Issue a list request to add resolver to cache and check if
       
   485 the registry has the expected version of the resolver.
       
   486 @param aResolverUid the custom resolver to create
       
   487 @param aVersion the expected version of the custom resolver. Check is skipped
       
   488   if aVersion is zero.
       
   489 */
       
   490 TBool CCustomResolverCacheTest::UseResolverCheckVersionL(TUid aResolverUid,
       
   491 														TInt aVersion)
       
   492 	{
       
   493 	TEComResolverParams resolverparams;
       
   494 	_LIT8(KDummyData,"dummy");
       
   495 	resolverparams.SetDataType(KDummyData);
       
   496 
       
   497 	TClientRequest clientReq;
       
   498 	RArray<TUid> extendedInterfaces;
       
   499 	RImplInfoArray* infoArray = iEComServer->ListImplementationsL(
       
   500 		KCustomResolverInterfaceUid, resolverparams, aResolverUid,
       
   501 		extendedInterfaces, clientReq);
       
   502 
       
   503 	TBool ret = (aVersion == 0);
       
   504 
       
   505 	// infoArray not pushed because there are no leave in this search.
       
   506 	for (TInt i = 0; !ret && i < infoArray->Count(); i++)
       
   507 		{
       
   508 		const CImplementationInformation* impl = (*infoArray)[i];
       
   509 		if (impl->ImplementationUid() == aResolverUid && impl->Version() == aVersion)
       
   510 			{
       
   511 			ret = ETrue;
       
   512 			}
       
   513 		}
       
   514 
       
   515 	infoArray->Reset();
       
   516 	delete infoArray;
       
   517 
       
   518 	return ret;
       
   519 	}
       
   520 
       
   521 /** utility to let other CActive s to run. */
       
   522 void CCustomResolverCacheTest::YieldToOtherCActive(TInt aMicroSeconds)
       
   523 	{
       
   524 	iHaltTimer->StartTimer(aMicroSeconds);
       
   525 	CActiveScheduler::Start();
       
   526 	}
       
   527 
       
   528 /** Call YieldToOtherCActive as many times as needed
       
   529 until aNumSeconds is reached. */
       
   530 void CCustomResolverCacheTest::WaitAsyncL(TInt aNumSeconds)
       
   531 	{
       
   532 	TTime start, now;
       
   533 	start.UniversalTime();
       
   534 	TTimeIntervalSeconds elapsed;
       
   535 
       
   536 	for (elapsed = 0; elapsed.Int() < aNumSeconds; )
       
   537 		{
       
   538 		AsyncEvents.ClearAll();
       
   539 		TInt seconds = (aNumSeconds - elapsed.Int());
       
   540 		YieldToOtherCActive(KOneSecond * seconds);
       
   541 		now.UniversalTime();
       
   542 		User::LeaveIfError(now.SecondsFrom(start, elapsed));
       
   543 		}
       
   544 	}
       
   545 
       
   546 /**
       
   547 This method is used in the situation that cache timer is already
       
   548 started when we load the given resolver. Then when cache timer
       
   549 expires, the resolver is not ripe to be evicted. Have to wait a
       
   550 second time.
       
   551 @param aResolverUid the Resolver to wait for evict.
       
   552 @return ETrue means the resolver is evicted correctly.
       
   553 		EFalse means error, i.e. test fail.
       
   554 */
       
   555 TBool CCustomResolverCacheTest::WaitForEvict(TUid aResolverUid)
       
   556 	{
       
   557 	TBool ret = EFalse;
       
   558 	// No point of waiting for 20s for cache timeout.
       
   559 	TInt waitMicroSec = KCustomResolverCacheTimeout + KOneSecond;
       
   560 	for (TInt i = 0; (i < 2) && !ret; i++)
       
   561 		{
       
   562 		AsyncEvents.ClearAll();
       
   563 		YieldToOtherCActive(waitMicroSec);
       
   564 		// Check which async event has stopped the activescheduler
       
   565 		test( AsyncEvents.IsSet(EAsyncEvent_CacheTimer) );
       
   566 		ret = ! HasResolverUid(aResolverUid);
       
   567 		}
       
   568 	return ret;
       
   569 	}
       
   570 
       
   571 //==========================================================
       
   572 // utilities to access internal data of CCustomResolverCache.
       
   573 // This is possible because CCustomResolverCacheTest is a friend.
       
   574 //===========================================================
       
   575 
       
   576 TInt CCustomResolverCacheTest::CacheSize()
       
   577 	{
       
   578 	return ResolverCache()->iResolvers.Count();
       
   579 	}
       
   580 
       
   581 TBool CCustomResolverCacheTest::HasResolverUid(TUid aUid)
       
   582 	{
       
   583 	for (TInt i = 0; i < ResolverCache()->iResolvers.Count(); i++)
       
   584 		{
       
   585 		if (ResolverCache()->iResolvers[i].iResolverUid == aUid)
       
   586 			{
       
   587 			return ETrue;
       
   588 			}
       
   589 		}
       
   590     return EFalse;
       
   591 	}
       
   592 
       
   593 TBool CCustomResolverCacheTest::QueueIsSorted()
       
   594 	{
       
   595 	CCustomResolverCache* theResolverCache = ResolverCache();
       
   596 	for (TInt i = 1; i < theResolverCache->iResolvers.Count(); i++)
       
   597 		{
       
   598 		if (theResolverCache->iResolvers[i-1].iResolverUid.iUid >=
       
   599 			theResolverCache->iResolvers[i].iResolverUid.iUid)
       
   600 			{
       
   601 			test.Printf(_L("Sort error: i-1 %d, 0x%8X, 0x%8X\n"), i-1,
       
   602 				theResolverCache->iResolvers[i-1].iResolverUid.iUid,
       
   603 				theResolverCache->iResolvers[i].iResolverUid.iUid	);
       
   604 			return EFalse;
       
   605 			}
       
   606 		}
       
   607     return ETrue;
       
   608 	}
       
   609 
       
   610 /**
       
   611 @SYMTestCaseID		SYSLIB-ECOM-CT-4012
       
   612 @SYMTestCaseDesc 	If a cached resolver is superseded by a new version, it
       
   613 	is evicted from cache.
       
   614 @SYMTestPriority 	High
       
   615 @SYMTestActions  	1. Use a custom resolver to get it in cache.
       
   616 	2. copy the upgrade version of the resolver to C: and wait for
       
   617 	   its discovery.
       
   618 @SYMTestExpectedResults 1. a/. The resolver is the base version.
       
   619        b/. It is added in the cache.
       
   620 	2. a/. Cache mgr receives upgrade notification (from CRegistryData).
       
   621 	   b/. The resolver entry disappears from cache and the cache timer is
       
   622 	       still running.
       
   623 @SYMCR CR1182
       
   624 */
       
   625 void CCustomResolverCacheTest::TestUpgradingCachedResolverL()
       
   626 	{
       
   627 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-4012 "));
       
   628 	// get the customer resolver in cache. It should be version 1.
       
   629 	test (UseResolverCheckVersionL(KMyResolverUid, 1));
       
   630 	// Check that KMyResolverUid is added to cache.
       
   631 	test(HasResolverUid(KMyResolverUid));
       
   632 
       
   633 	// Need an extra item in cache to get Bullseye to check off
       
   634 	// a conditional. It is not an active ingredient of this test.
       
   635 	UseResolverCheckVersionL(KDummyResolverUid1, 0);
       
   636 
       
   637 	// Copy the upgrade to C: drive
       
   638 	EComTestUtils::FileManCopyFileL(KRscUpgradeInZ, KRscUpgradeInC);
       
   639 	EComTestUtils::FileManCopyFileL(KDllUpgradeInZ, KDllUpgradeInC);
       
   640 
       
   641 	// Let CDiscoverer discover the resource file.
       
   642 	AsyncEvents.ClearAll();
       
   643 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
   644 
       
   645 	// Check which async event has stopped the activescheduler
       
   646 	test( AsyncEvents.IsSet(EAsyncEvent_ImplUpgrade) );
       
   647 
       
   648 	// And the cache entry should be gone.
       
   649 	test(! HasResolverUid(KMyResolverUid));
       
   650 
       
   651 	// cleanup. NB: we never loaded the DLL in C: drive so
       
   652 	// no need to worry about lazy dll unloading.
       
   653 	EComTestUtils::FileManDeleteFileL(KRscUpgradeInC);
       
   654 	EComTestUtils::FileManDeleteFileL(KDllUpgradeInC);
       
   655 	}
       
   656 
       
   657 /**
       
   658 @SYMTestCaseID		SYSLIB-ECOM-CT-4013
       
   659 @SYMTestCaseDesc 	Verify a cached DLL cannot be deleted until it
       
   660 	is removed from cache. This test serves as a sanity check that
       
   661 	ECOM does need these notifications to trigger unloading DLL
       
   662 	on SWI and BUR events.
       
   663 @SYMTestPriority 	Medium
       
   664 @SYMTestActions  	1. Use a RW drive resolver to get it in cache.
       
   665 	2. Try to delete the DLL within default cache timeout period.
       
   666     3. Try again after it is evicted from cache.
       
   667 @SYMTestExpectedResults 1. The resolver is added in cache.
       
   668 	2. Get KErrAccessDenied error.
       
   669 	3. The delete is either KErrNone or KErrNotFound because in step 2
       
   670 	   even though the return code is -21, the file may be actually gone.
       
   671 @SYMCR CR1182
       
   672 */
       
   673 void CCustomResolverCacheTest::TestDeletingCachedResolverL()
       
   674 	{
       
   675 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-4013 "));
       
   676 	// NB: lazy Dll unloading interferes with this test.
       
   677 	// Best to run this test at the end.
       
   678 	WaitForLazyUnloadingL();
       
   679 
       
   680 	// There is only 1 version of 200126CD. No need to check version.
       
   681 	// So ignore the return code.
       
   682 	UseResolverCheckVersionL(KDummyResolverUid1, 0);
       
   683 
       
   684 	// Check that it is added to cache.
       
   685 	test( HasResolverUid(KDummyResolverUid1) );
       
   686 
       
   687 	TInt err(KErrNone);
       
   688 	TRAP(err, EComTestUtils::FileManDeleteFileL(KDummyDllInC));
       
   689 
       
   690 #ifndef __WINSCW__
       
   691 	// On hw you can delete the DLL while it is loaded.
       
   692 	if (err == KErrNone)
       
   693 		{
       
   694 		test.Printf(_L("Delete test: RFs allows deletion of loaded DLL on hw. Test not run.\n"));
       
   695 		EComTestUtils::FileManCopyFileL(KDummyDllInZ, KDummyDllInC);
       
   696 		return;
       
   697 		}
       
   698 #endif
       
   699 
       
   700 	test(err == KErrAccessDenied);
       
   701 
       
   702 	// Wait for its eviction after cache timeout.
       
   703 	AsyncEvents.ClearAll();
       
   704 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
   705 
       
   706 	// Check which async event has stopped the activescheduler
       
   707 	test( AsyncEvents.IsSet(EAsyncEvent_CacheTimer) );
       
   708 	// Check the resolver is evicted
       
   709 	test( !HasResolverUid(KDummyResolverUid1) );
       
   710 
       
   711 	TRAP(err, EComTestUtils::FileManDeleteFileL(KDummyDllInC));
       
   712 	test(err == KErrNone || err == KErrNotFound);
       
   713 
       
   714 	// restore the file
       
   715 	EComTestUtils::FileManCopyFileL(KDummyDllInZ, KDummyDllInC);
       
   716 	}
       
   717 
       
   718 /**
       
   719 @SYMTestCaseID		SYSLIB-ECOM-UT-4015
       
   720 @SYMTestCaseDesc 	Verify cache queue does not grow beyond the max
       
   721 	queue size. Verify when a resolver is added to a full cache,
       
   722 	the one to evict is the least recently used.
       
   723 
       
   724 	There are 3 versions of this test. In Pattern1, the LRU entry
       
   725 	has UID value which is the smallest of the 5 resolvers.
       
   726 	In pattern 2, UID of the LRU is greatest. In pattern 3, UID of the
       
   727 	LRU is the second smallest.
       
   728 @SYMTestPriority 	High
       
   729 @SYMTestActions  	1. Use 4 different resolvers to fill up the cache.
       
   730 	2. Use a fifth one to bump off the least recently used entry.
       
   731     Run these two steps with the LRU entry in different positions in the
       
   732 	queue, i.e. it is first, second, and last in the queue.
       
   733 @SYMTestExpectedResults 1. The cache has 4 entries and is sorted in UID order.
       
   734 	2. The oldest entry is gone from cache. The last one used is in cache.
       
   735 @SYMCR CR1182
       
   736 */
       
   737 void CCustomResolverCacheTest::TestCacheQueueFullPattern1L()
       
   738 	{
       
   739 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4015 "));
       
   740 	RArray<TUid> resolverlist(1);
       
   741 	CleanupClosePushL(resolverlist);
       
   742 
       
   743 	// NB: the following insertion order caused the problem found in
       
   744 	// INC115472. Hence there will be a check in DoQueueFullTestL
       
   745 	// that the cache queue is sorted correctly.
       
   746 	//
       
   747 	// Condition for inc115472 is first insert an UID of 0xA???????
       
   748 	// in an empty queue. Next insert an UID 0x2???????. The overflow
       
   749 	// error causes them to be placed in the wrong order.
       
   750 	resolverlist.AppendL(KDummyResolverUid2);
       
   751 	resolverlist.AppendL(KDummyResolverUid1);
       
   752 	resolverlist.AppendL(KExampleResolverUid);
       
   753 	resolverlist.AppendL(KMyResolverUid);
       
   754 	resolverlist.AppendL(KDummyResolverUid3);
       
   755 	DoQueueFullTestL(resolverlist);
       
   756 	CleanupStack::PopAndDestroy(&resolverlist);
       
   757 	}
       
   758 
       
   759 // In pattern 2 the oldest entry in cache has the largest UID value.
       
   760 void CCustomResolverCacheTest::TestCacheQueueFullPattern2L()
       
   761 	{
       
   762 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4015 "));
       
   763 	RArray<TUid> resolverlist(1);
       
   764 	CleanupClosePushL(resolverlist);
       
   765 	resolverlist.AppendL(KDummyResolverUid1);
       
   766 	resolverlist.AppendL(KDummyResolverUid2);
       
   767 	resolverlist.AppendL(KDummyResolverUid3);
       
   768 	resolverlist.AppendL(KExampleResolverUid);
       
   769 	resolverlist.AppendL(KMyResolverUid);
       
   770 	DoQueueFullTestL(resolverlist);
       
   771 	CleanupStack::PopAndDestroy(&resolverlist);
       
   772 	}
       
   773 
       
   774 // In pattern 3 the UID of the oldest entry has the second smallest value.
       
   775 void CCustomResolverCacheTest::TestCacheQueueFullPattern3L()
       
   776 	{
       
   777 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4015 "));
       
   778 	RArray<TUid> resolverlist(1);
       
   779 	CleanupClosePushL(resolverlist);
       
   780 	resolverlist.AppendL(KDummyResolverUid3);
       
   781 	resolverlist.AppendL(KDummyResolverUid1);
       
   782 	resolverlist.AppendL(KDummyResolverUid2);
       
   783 	resolverlist.AppendL(KExampleResolverUid);
       
   784 	resolverlist.AppendL(KMyResolverUid);
       
   785 	DoQueueFullTestL(resolverlist);
       
   786 	CleanupStack::PopAndDestroy(&resolverlist);
       
   787 	}
       
   788 
       
   789 void CCustomResolverCacheTest::DoQueueFullTestL(const RArray<TUid>& aResolverList)
       
   790 	{
       
   791 	// ensure cache is empty.
       
   792 	test(CacheSize() == 0);
       
   793 
       
   794 	TInt maxQueueSize = ResolverCache()->iMaxCacheSize;
       
   795 	test(aResolverList.Count() > maxQueueSize);
       
   796 
       
   797 	// Put 4 resolvers in the cache. Pause in between so that the time tick
       
   798 	// of each entry is different. CacheMissPerfTestL in t_resolverperf exercises
       
   799 	// the code path that time ticks are the same.
       
   800 	const TInt KInBetweenDelay = 100000;
       
   801 	TInt i;
       
   802 	for (i = 0; i < maxQueueSize; i++)
       
   803 		{
       
   804 		UseResolverCheckVersionL(aResolverList[i], 0);
       
   805 		User::AfterHighRes(KInBetweenDelay);
       
   806 		}
       
   807 
       
   808 	// Check cache is full.
       
   809 	test(CacheSize() == maxQueueSize);
       
   810 	// Check cache is sorted properly
       
   811 	test( QueueIsSorted() );
       
   812 
       
   813 	// Add one more to cache.
       
   814 	UseResolverCheckVersionL(aResolverList[maxQueueSize], 0);
       
   815 
       
   816 	// Check that cache size is still full - not exceeding limit.
       
   817 	test(CacheSize() == maxQueueSize);
       
   818 
       
   819 	// Want to check LRU is gone and the last resolver is now in cache.
       
   820 	test(! HasResolverUid(aResolverList[0]));
       
   821 	test( QueueIsSorted() );
       
   822 	// Because of the above 3 checks, this is really redundant.
       
   823 	test(HasResolverUid(aResolverList[maxQueueSize]));
       
   824 
       
   825 	// Because the timestamps of the cache entries are staggered
       
   826 	// 100 ms apart, the mgr can only kick out 1 item at each timer expiry.
       
   827 	// So let the cache mgr exercise this code path.
       
   828 	TInt n = 0;
       
   829 	while (CacheSize() > 0)
       
   830 		{
       
   831 		AsyncEvents.ClearAll();
       
   832 		YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
   833 		// Check which async event has stopped the activescheduler
       
   834 		test( AsyncEvents.IsSet(EAsyncEvent_CacheTimer) );
       
   835 		n++;
       
   836 		}
       
   837 
       
   838 	// n should be five. aResolverList[0] is bumped due to queue full.
       
   839 	// So the first timer expire will not find any expired entry.
       
   840 	test.Printf(_L("Gone through %d loops to clear out cache.\n"), n);
       
   841 
       
   842 	test(n > maxQueueSize);
       
   843 	}
       
   844 
       
   845 /**
       
   846 @SYMTestCaseID		SYSLIB-ECOM-UT-4016
       
   847 @SYMTestCaseDesc 	Verify resolver is unloaded after the specified timeout.
       
   848 @SYMTestPriority 	Medium
       
   849 @SYMTestActions  	1. Use a resolver to get it in cache.
       
   850 	2. Measure how long the entry stays in cache before it is evicted.
       
   851 @SYMTestExpectedResults The time should be >= default timeout but
       
   852 	<= (timeout + 0.5s).
       
   853 @SYMCR CR1182
       
   854 */
       
   855 void CCustomResolverCacheTest::TestCacheTimerAccuracyL()
       
   856 	{
       
   857 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4016 "));
       
   858 	TTime start;
       
   859 	start.UniversalTime();
       
   860 
       
   861 	UseResolverCheckVersionL(KMyResolverUid, 0);
       
   862 	test( HasResolverUid(KMyResolverUid) );
       
   863 
       
   864 	// Wait for cache timeout
       
   865 	AsyncEvents.ClearAll();
       
   866 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
   867 	// Check which async event has stopped the activescheduler
       
   868 	test( AsyncEvents.IsSet(EAsyncEvent_CacheTimer) );
       
   869 
       
   870 	TInt microseconds = CalcElapsedMicroseconds(start);
       
   871 	test.Printf(_L("Resolver is cached for %d microseconds\n"), microseconds);
       
   872 
       
   873 	TInt tickperiod;
       
   874 	User::LeaveIfError(HAL::Get(HALData::ESystemTickPeriod, tickperiod));
       
   875 	TInt lowerLimit = KCustomResolverCacheTimeout - tickperiod;
       
   876 	test(microseconds > lowerLimit);
       
   877 
       
   878 	// The upper bound is tricky because there is no gaurantee on
       
   879 	// CTimer accuracy.
       
   880 	test(microseconds < (KCustomResolverCacheTimeout + KHalfSecond));
       
   881 	}
       
   882 
       
   883 /**
       
   884 @SYMTestCaseID		SYSLIB-ECOM-UT-4017
       
   885 @SYMTestCaseDesc 	Verify after a cache hit the time to live of the entry
       
   886 	is extended.
       
   887 @SYMTestPriority 	High
       
   888 @SYMTestActions  	1. Record start time.
       
   889 	2. Use a resolver to put it in cache.
       
   890 	3. After 1 s use it again.
       
   891 	4  Wait for its eviction.
       
   892 	5. Check how long the entry stays in cache.
       
   893 @SYMTestExpectedResults The time should be >= 5 seconds.
       
   894 @SYMCR CR1182
       
   895 */
       
   896 void CCustomResolverCacheTest::TestTimestampUpdateOnCacheHitL()
       
   897 	{
       
   898 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4017 "));
       
   899 	// Check that the resolver is not in cache.
       
   900 	test(! HasResolverUid(KMyResolverUid) );
       
   901 
       
   902 	TTime start;
       
   903 	start.UniversalTime();
       
   904 
       
   905 	UseResolverCheckVersionL(KMyResolverUid, 0);
       
   906 	test( HasResolverUid(KMyResolverUid) );
       
   907 
       
   908 	// Delay one second and use it again.
       
   909 	User::AfterHighRes(KOneSecond);
       
   910 	UseResolverCheckVersionL(KMyResolverUid, 0);
       
   911 
       
   912 	// Wait for its eviction
       
   913 	while ( HasResolverUid(KMyResolverUid) )
       
   914 		{
       
   915 		AsyncEvents.ClearAll();
       
   916 		YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
   917 		// Check which async event has stopped the activescheduler
       
   918 		test( AsyncEvents.IsSet(EAsyncEvent_CacheTimer) );
       
   919 		}
       
   920 
       
   921 	TInt microseconds = CalcElapsedMicroseconds(start);
       
   922 	test.Printf(_L("With cache hit, resolver is cached for %d microseconds\n"), microseconds);
       
   923 
       
   924 	TInt tickperiod;
       
   925 	User::LeaveIfError(HAL::Get(HALData::ESystemTickPeriod, tickperiod));
       
   926 	TInt lowerLimit = KCustomResolverCacheTimeout + KOneSecond - tickperiod;
       
   927 	test(microseconds > lowerLimit);
       
   928 	}
       
   929 
       
   930 /**
       
   931 @SYMTestCaseID		SYSLIB-ECOM-UT-4018
       
   932 @SYMTestCaseDesc 	Verify at SWI start RW resolvers are evicted from cache.
       
   933 	Verify during SWI ROM resolvers are cached but RW resolvers are not.
       
   934 @SYMTestPriority 	High
       
   935 @SYMTestActions  	1. Add a RW resolver to cache.
       
   936 	2. Send a SWI start signal.
       
   937 	3. Use a RW resolver.
       
   938 	4  Use a ROM resolver.
       
   939 @SYMTestExpectedResults 1. The RW resolver is in cache.
       
   940 	2. The cache entry is evicted.
       
   941 	3. The RW resolver is not cached.
       
   942 	4. The ROM resolver is cached.
       
   943 @SYMCR CR1182
       
   944 */
       
   945 void CCustomResolverCacheTest::TestSWIDisableRwResolverCachingL()
       
   946 	{
       
   947 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4018 "));
       
   948 	// The TPropertyManager protocol to setup to use a system category P&S.
       
   949 	TInt r = PropertyManager::DeleteProperty(KUidSystemCategory,
       
   950 		KSAUidSoftwareInstallKeyValue);
       
   951 	test(r == KErrNone);
       
   952 	r = PropertyManager::DefineProperty(KUidSystemCategory,
       
   953 		KSAUidSoftwareInstallKeyValue, RProperty::EInt);
       
   954 	test(r == KErrNone);
       
   955 
       
   956 	// Use a resolver in C: drive.
       
   957 	UseResolverCheckVersionL(KDummyResolverUid1, 0);
       
   958 	// Check that it is added to cache.
       
   959 	test( HasResolverUid(KDummyResolverUid1) );
       
   960 
       
   961 	// Need a ROM entry in cache to get Bullseye to check off
       
   962 	// a conditional. It is not an active ingredient of this test.
       
   963 	UseResolverCheckVersionL(KMyResolverUid, 0);
       
   964 
       
   965 	// SWI start
       
   966 	r = PropertyManager::SetProperty(KUidSystemCategory,
       
   967 		KSAUidSoftwareInstallKeyValue,ESASwisInstall);
       
   968 	test(r == KErrNone);
       
   969 
       
   970 	// Let CSwiChangeNotifier receive the notification
       
   971 	AsyncEvents.ClearAll();
       
   972 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
   973 	// Check we receive the correct event
       
   974 	test( AsyncEvents.IsSet(EAsyncEvent_SwiStart) );
       
   975 
       
   976 	// Check the RW resolver is evicted
       
   977 	test(! HasResolverUid(KDummyResolverUid1) );
       
   978 
       
   979 	// during SWI RW resolver will not be cached.
       
   980 	UseResolverCheckVersionL(KDummyResolverUid1, 0);
       
   981 	test(! HasResolverUid(KDummyResolverUid1) );
       
   982 
       
   983 	// But ROM resolvers are still cached.
       
   984 	UseResolverCheckVersionL(KDummyResolverUid2, 0);
       
   985 	test( HasResolverUid(KDummyResolverUid2) );
       
   986 
       
   987 	// And the ROM resolvers are evicted after 4 s as usual.
       
   988 	// Note that we have KMyResolverUid and KDummyResolverUid2 in cache
       
   989 	TBool b = WaitForEvict(KDummyResolverUid2);
       
   990 	if (! b)
       
   991 		{ // got KMyResolverUid only, need a second wait.
       
   992 		b = WaitForEvict(KDummyResolverUid2);
       
   993 		}
       
   994 	test(b);
       
   995 
       
   996 	// Just for completeness. Do not really need this
       
   997 	// for Bullseye Coverage.
       
   998 	r = PropertyManager::SetProperty(KUidSystemCategory,
       
   999 		KSAUidSoftwareInstallKeyValue,ESASwisNone);
       
  1000 	test(r == KErrNone);
       
  1001 	// Let CSwiChangeNotifier receive the notification
       
  1002 	AsyncEvents.ClearAll();
       
  1003 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
  1004 	// Check we receive the correct event
       
  1005 	test( AsyncEvents.IsSet(EAsyncEvent_SwiEnd) );
       
  1006 	}
       
  1007 
       
  1008 /**
       
  1009 @SYMTestCaseID		SYSLIB-ECOM-UT-4019
       
  1010 @SYMTestCaseDesc 	Verify at BUR start RW resolvers are evicted from cache.
       
  1011 	Verify during BUR ROM resolvers are cached but RW resolvers are not.
       
  1012 @SYMTestPriority 	High
       
  1013 @SYMTestActions  	1. Add a RW resolver to cache.
       
  1014 	2. Send a BUR start signal.
       
  1015 	3. Use a RW resolver.
       
  1016 	4  Use a ROM resolver.
       
  1017 @SYMTestExpectedResults 1. The RW resolver is in cache.
       
  1018 	2. The cache entry is evicted.
       
  1019 	3. The RW resolver is not cached.
       
  1020 	4. The ROM resolver is cached.
       
  1021 @SYMCR CR1182
       
  1022 */
       
  1023 void CCustomResolverCacheTest::TestBurDisableRwResolverCachingL()
       
  1024 	{
       
  1025 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4019 "));
       
  1026 	// setup backup session wrapper
       
  1027 	CBaBackupSessionWrapper* ba = CBaBackupSessionWrapper::NewL();
       
  1028 	CleanupStack::PushL(ba);
       
  1029 	TBackupOperationAttributes attribs;
       
  1030 	attribs.iFileFlag=MBackupObserver::EReleaseLockNoAccess;
       
  1031 	attribs.iOperation=MBackupOperationObserver::EStart;
       
  1032 
       
  1033 	// The backup notifier of ECOM is not registered with
       
  1034 	// BA server at construction time. It delays 15 s.
       
  1035 	// So we have to wait this long.
       
  1036 	WaitAsyncL(16);
       
  1037 
       
  1038 	// Use a resolver in C: drive.
       
  1039 	UseResolverCheckVersionL(KDummyResolverUid1, 0);
       
  1040 	// Check that it is added to cache.
       
  1041 	test( HasResolverUid(KDummyResolverUid1) );
       
  1042 
       
  1043 	// Need a ROM entry in cache to get Bullseye to check off
       
  1044 	// a conditional. It is not an active ingredient of this test.
       
  1045 	UseResolverCheckVersionL(KMyResolverUid, 0);
       
  1046 
       
  1047 	// backup start
       
  1048 	ba->NotifyBackupOperationL(attribs);
       
  1049 	// Let backup notifier receive the backup start
       
  1050 	AsyncEvents.ClearAll();
       
  1051 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
  1052 	// Check we receive the backup start notification
       
  1053 	test( AsyncEvents.IsSet(EAsyncEvent_BurStart) );
       
  1054 
       
  1055 	// Check the RW resolver is evicted
       
  1056 	test(! HasResolverUid(KDummyResolverUid1) );
       
  1057 
       
  1058 	// during BUR RW resolver will not be cached.
       
  1059 	UseResolverCheckVersionL(KDummyResolverUid1, 0);
       
  1060 	test(! HasResolverUid(KDummyResolverUid1) );
       
  1061 
       
  1062 	// But ROM resolvers are still cached.
       
  1063 	UseResolverCheckVersionL(KDummyResolverUid2, 0);
       
  1064 	test( HasResolverUid(KDummyResolverUid2) );
       
  1065 
       
  1066 	// And the ROM resolvers are evicted after 4 s as usual.
       
  1067 	// Note that we have KMyResolverUid and KDummyResolverUid2 in cache
       
  1068 	TBool b = WaitForEvict(KDummyResolverUid2);
       
  1069 	if (! b)
       
  1070 		{ // got KMyResolverUid only, need a second wait.
       
  1071 		b = WaitForEvict(KDummyResolverUid2);
       
  1072 		}
       
  1073 	test(b);
       
  1074 
       
  1075 	// Do this for Bullseye Coverage of production code.
       
  1076 	// NB: attribs.iFileFlag stays the same
       
  1077 	attribs.iOperation=MBackupOperationObserver::EEnd;
       
  1078 	ba->NotifyBackupOperationL(attribs);
       
  1079 	// Let backup notifier receive it
       
  1080 	AsyncEvents.ClearAll();
       
  1081 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
  1082 	// Check we receive the backup notification
       
  1083 	test( AsyncEvents.IsSet(EAsyncEvent_BurEnd) );
       
  1084 
       
  1085 	CleanupStack::PopAndDestroy(ba);
       
  1086 
       
  1087 	// to earn another Bullseye check mark.
       
  1088 	CEComServer::NotifyEvents(iEComServer, ECallBackId_None, NULL);
       
  1089 	}
       
  1090 
       
  1091 /**
       
  1092 @SYMTestCaseID		SYSLIB-ECOM-UT-4021
       
  1093 @SYMTestCaseDesc 	Verify the cache timer and data to keep track of
       
  1094 	cache entry time to live are immune to device clock change.
       
  1095 @SYMTestPriority 	High
       
  1096 @SYMTestActions  	1. Put two resolvers in cache at 20 ticks apart.
       
  1097 	2. Spring clock forward by 5 s (1 + default cache timeout).
       
  1098 	3. Measure how long the first resolver is cached.
       
  1099 	4. Measure how long the second resolver is cached.
       
  1100 	Repeat steps 1 to 4 in setting clock backward.
       
  1101 @SYMTestExpectedResults Both resolvers are cached for ~ 4 s
       
  1102 	(default cache timeout value).
       
  1103 @SYMCR CR1182
       
  1104 */
       
  1105 void CCustomResolverCacheTest::TestClockChangeHasNoEffectOnCacheTimeoutL()
       
  1106 	{
       
  1107 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4021 "));
       
  1108 	TInt tp;
       
  1109 	User::LeaveIfError(HAL::Get(HALData::ESystemTickPeriod, tp));
       
  1110 	TInt delayInBetween = tp * 20;
       
  1111    	test.Printf(_L("ESystemTickPeriod: %d; delayInBetween: %d;\n"), tp, delayInBetween);
       
  1112 
       
  1113 
       
  1114 	TTime beforeDelay;
       
  1115 	beforeDelay.UniversalTime();
       
  1116 
       
  1117 	UseResolverCheckVersionL(KDummyResolverUid1, 0);
       
  1118 	test( HasResolverUid(KDummyResolverUid1) );
       
  1119 
       
  1120 	User::AfterHighRes(delayInBetween);
       
  1121 	TInt elapsedBeforeTimeChange = CalcElapsedMicroseconds(beforeDelay);
       
  1122 
       
  1123 	UseResolverCheckVersionL(KDummyResolverUid2, 0);
       
  1124 	test( HasResolverUid(KDummyResolverUid2) );
       
  1125 
       
  1126 	TTimeIntervalMicroSeconds AmountOfChange(
       
  1127 		MAKE_TINT64(0, KCustomResolverCacheTimeout+KOneSecond) );
       
  1128 
       
  1129 	// Now set device clock forward
       
  1130 	TTime t;
       
  1131 	t.UniversalTime();
       
  1132 	t += AmountOfChange;
       
  1133 	User::LeaveIfError( User::SetUTCTime(t) );
       
  1134 
       
  1135 	t.UniversalTime(); // need this, apparently SetUTCTime does rounding
       
  1136 
       
  1137 	// Wait for cache timeout
       
  1138 	AsyncEvents.ClearAll();
       
  1139 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
  1140 	// Check which async event has stopped the activescheduler
       
  1141 	test( AsyncEvents.IsSet(EAsyncEvent_CacheTimer) );
       
  1142 
       
  1143 	TInt microseconds = CalcElapsedMicroseconds(t);
       
  1144 	// compensate for the 20 ticks delay
       
  1145 	microseconds += elapsedBeforeTimeChange;
       
  1146 	test.Printf(_L("Clock forward: 1st resolver is cached for %d microseconds\n"), microseconds);
       
  1147 	test(! HasResolverUid(KDummyResolverUid1) );
       
  1148 	// Check duration is between 4 to 4.5 s.
       
  1149 	TInt lowerLimit = KCustomResolverCacheTimeout - (tp*3);
       
  1150 	TInt upperLimit = (KCustomResolverCacheTimeout + KHalfSecond);
       
  1151    	test.Printf(_L("lowerLimit: %d; upperLimit: %d\n"), lowerLimit, upperLimit);	
       
  1152 	test(microseconds > lowerLimit);
       
  1153 
       
  1154 	// upper limit is tricky because there is no guarantee on CTimer
       
  1155 	// accuracy.
       
  1156 	test(microseconds <= upperLimit);
       
  1157 
       
  1158 	// Wait for eviction of the second resolver
       
  1159 	AsyncEvents.ClearAll();
       
  1160 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
  1161 	// Check which async event has stopped the activescheduler
       
  1162 	test( AsyncEvents.IsSet(EAsyncEvent_CacheTimer) );
       
  1163 
       
  1164 	microseconds = CalcElapsedMicroseconds(t);
       
  1165 	test.Printf(_L("Clock forward: 2nd resolver is cached for %d microseconds\n"), microseconds);
       
  1166 	test(! HasResolverUid(KDummyResolverUid2) );
       
  1167 	// Check duration is between 4 to 4.5 s.
       
  1168 	test(microseconds > lowerLimit);
       
  1169 	test(microseconds <= upperLimit);
       
  1170 
       
  1171 	//
       
  1172 	// Repeat for setting clock backward.
       
  1173 	//
       
  1174 	beforeDelay.UniversalTime();
       
  1175 
       
  1176 	UseResolverCheckVersionL(KDummyResolverUid1, 0);
       
  1177 	test( HasResolverUid(KDummyResolverUid1) );
       
  1178 
       
  1179 	User::AfterHighRes(delayInBetween);
       
  1180 	elapsedBeforeTimeChange = CalcElapsedMicroseconds(beforeDelay);
       
  1181 
       
  1182 	UseResolverCheckVersionL(KDummyResolverUid2, 0);
       
  1183 	test( HasResolverUid(KDummyResolverUid2) );
       
  1184 
       
  1185 	// Now set device clock backward
       
  1186 	t.UniversalTime();
       
  1187 	t -= AmountOfChange;
       
  1188 	User::LeaveIfError( User::SetUTCTime(t) );
       
  1189 	t.UniversalTime();
       
  1190 
       
  1191 	// Wait for cache timeout
       
  1192 	AsyncEvents.ClearAll();
       
  1193 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
  1194 	// Check which async event has stopped the activescheduler
       
  1195 	test( AsyncEvents.IsSet(EAsyncEvent_CacheTimer) );
       
  1196 
       
  1197 	microseconds = CalcElapsedMicroseconds(t);
       
  1198 	// compensate for the 20 ticks delay
       
  1199 	microseconds += elapsedBeforeTimeChange;
       
  1200 	test.Printf(_L("Clock backward: 1st resolver is cached for %d microseconds\n"), microseconds);
       
  1201 	test(! HasResolverUid(KDummyResolverUid1) );
       
  1202 	// Check duration is between 4 to 4.5 s.
       
  1203 	test(microseconds > lowerLimit);
       
  1204 	test(microseconds <= (KCustomResolverCacheTimeout + KHalfSecond));
       
  1205 
       
  1206 	// Wait for eviction of the second resolver
       
  1207 	AsyncEvents.ClearAll();
       
  1208 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
  1209 	// Check which async event has stopped the activescheduler
       
  1210 	test( AsyncEvents.IsSet(EAsyncEvent_CacheTimer) );
       
  1211 
       
  1212 	microseconds = CalcElapsedMicroseconds(t);
       
  1213 	test.Printf(_L("Clock backward: 2nd resolver is cached for %d microseconds\n"), microseconds);
       
  1214 	test(! HasResolverUid(KDummyResolverUid2) );
       
  1215 	// Check duration is between 4 to 4.5 s.
       
  1216 	test(microseconds > lowerLimit);
       
  1217 	test(microseconds <= (KCustomResolverCacheTimeout + KHalfSecond));
       
  1218 	}
       
  1219 
       
  1220 /**
       
  1221 @SYMTestCaseID		SYSLIB-ECOM-UT-4022
       
  1222 @SYMTestCaseDesc 	Verify caching runs normally if queue size is zero.
       
  1223 @SYMTestPriority 	Medium
       
  1224 @SYMTestActions  	1. Set max. cache size to 0.
       
  1225 	2. Use a custom resolver.
       
  1226 @SYMTestExpectedResults No leave on the list request and cache is empty.
       
  1227 @SYMCR CR1182
       
  1228 */
       
  1229 void CCustomResolverCacheTest::TestCacheSizeZeroL()
       
  1230 	{
       
  1231 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4022 "));
       
  1232 	ResolverCache()->iMaxCacheSize = 0;
       
  1233 	UseResolverCheckVersionL(KMyResolverUid, 0);
       
  1234 	test(! HasResolverUid(KMyResolverUid) );
       
  1235 	}
       
  1236 
       
  1237 /**
       
  1238 @SYMTestCaseID		SYSLIB-ECOM-UT-4023
       
  1239 @SYMTestCaseDesc 	Verify caching runs normally if cache timeout is zero.
       
  1240 @SYMTestPriority 	Medium
       
  1241 @SYMTestActions  	1. Set cache time-to-live to zero.
       
  1242 	2. Use a custom resolver.
       
  1243 @SYMTestExpectedResults No leave on the list request and cache is empty.
       
  1244 @SYMCR CR1182
       
  1245 */
       
  1246 void CCustomResolverCacheTest::TestCacheTimeoutZeroL()
       
  1247 	{
       
  1248 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4023 "));
       
  1249 	TInt systemTickPeriod = ResolverCache()->iSystemTickPeriod;
       
  1250 	// mimic CCustomResolverCache calculate the time-to-live value.
       
  1251 	const TInt KZeroTimeout = 0;
       
  1252 	ResolverCache()->iEntryTimeToLive = (KZeroTimeout +
       
  1253 		systemTickPeriod - 1) / systemTickPeriod;
       
  1254 
       
  1255 	// run the test
       
  1256 	UseResolverCheckVersionL(KMyResolverUid, 0);
       
  1257 	test(! HasResolverUid(KMyResolverUid) );
       
  1258 	}
       
  1259 
       
  1260 /**
       
  1261 @SYMTestCaseID		SYSLIB-ECOM-UT-4024
       
  1262 @SYMTestCaseDesc 	CCustomResolverCache uses system tick to track entry
       
  1263 	time-to-live. The counter wraps around every 777 days. This test
       
  1264 	checks when wrap around occurs cached entry is purged correctly.
       
  1265 @SYMTestPriority 	Medium
       
  1266 @SYMTestActions  	1. Use a resolver to get it in cache.
       
  1267 	2. Set its time-of-use to 0xFFFFFFFF.
       
  1268 	3. Wait for cache timer expire.
       
  1269 @SYMTestExpectedResults The entry is evicted on first timer expiry and
       
  1270 	the entry stays in cache for ~ 4s.
       
  1271 @SYMCR CR1182
       
  1272 */
       
  1273 void CCustomResolverCacheTest::TestCounterWrapAroundL()
       
  1274 	{
       
  1275 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4024 "));
       
  1276 	TTime start;
       
  1277 	start.UniversalTime();
       
  1278 
       
  1279 	UseResolverCheckVersionL(KMyResolverUid, 0);
       
  1280 	RResolverCacheEntry& entry = ResolverCache()->iResolvers[0];
       
  1281 	test( entry.iResolverUid == KMyResolverUid );
       
  1282 
       
  1283 	// Set time-of-use to edge of wrap around
       
  1284 	entry.iLastUse.iTicks = KMaxTUint;
       
  1285 
       
  1286 	// Wait for cache timeout
       
  1287 	AsyncEvents.ClearAll();
       
  1288 	YieldToOtherCActive(KIndefiniteWait);  // 20 s
       
  1289 	// Check which async event has stopped the activescheduler
       
  1290 	test( AsyncEvents.IsSet(EAsyncEvent_CacheTimer) );
       
  1291 
       
  1292 	TInt microseconds = CalcElapsedMicroseconds(start);
       
  1293 	test.Printf(_L("Wrap around: resolver is cached for %d microseconds\n"), microseconds);
       
  1294 
       
  1295 	TInt tickperiod;
       
  1296 	User::LeaveIfError(HAL::Get(HALData::ESystemTickPeriod, tickperiod));
       
  1297 	TInt lowerLimit = KCustomResolverCacheTimeout - tickperiod;
       
  1298 	test(microseconds > lowerLimit);
       
  1299 	// Upper limit must have a wide margin because there is no gaurantee
       
  1300 	// on CTimer accuracy.
       
  1301 	test(microseconds < (KCustomResolverCacheTimeout + KHalfSecond));
       
  1302 	}
       
  1303 
       
  1304 /**
       
  1305 @SYMTestCaseID		SYSLIB-ECOM-UT-4025
       
  1306 @SYMTestCaseDesc 	Verify if cannot find the NewL method in the proxy
       
  1307 	instantiation table, ECOM returns KEComErrNoResolver
       
  1308 @SYMTestPriority 	Medium
       
  1309 @SYMTestActions  	Use a resolver whose proxy table has the wrong Impl. Uid.
       
  1310 @SYMTestExpectedResults Get KEComErrNoResolver error
       
  1311 @SYMCR CR1182
       
  1312 */
       
  1313 void CCustomResolverCacheTest::TestResolverWithBadProxyTable()
       
  1314 	{
       
  1315 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-UT-4025 "));
       
  1316 	const TUid KBadResolverUid = {0x10009DDF};
       
  1317 	TRAPD(err, UseResolverCheckVersionL(KBadResolverUid, 0) );
       
  1318 	test(err == KEComErrNoResolver);
       
  1319 	}
       
  1320 
       
  1321 /** wrapper to run all the Basic and OOM tests */
       
  1322 void CCustomResolverCacheTest::RunAllTestsL()
       
  1323 	{
       
  1324 	CopyPluginsL();
       
  1325 
       
  1326 	test.Next(_L("Basic TestCounterWrapAroundL"));
       
  1327 	DoBasicTestL(&CCustomResolverCacheTest::TestCounterWrapAroundL);
       
  1328 
       
  1329 	test.Next(_L("Basic TestUpgradingCachedResolverL"));
       
  1330 	DoBasicTestL(&CCustomResolverCacheTest::TestUpgradingCachedResolverL);
       
  1331 
       
  1332 	test.Next(_L("Basic TestCacheQueueFullPattern1L"));
       
  1333 	DoBasicTestL(&CCustomResolverCacheTest::TestCacheQueueFullPattern1L);
       
  1334 
       
  1335 	test.Next(_L("Basic TestCacheQueueFullPattern2L"));
       
  1336 	DoBasicTestL(&CCustomResolverCacheTest::TestCacheQueueFullPattern2L);
       
  1337 
       
  1338 	test.Next(_L("Basic TestCacheQueueFullPattern3L"));
       
  1339 	DoBasicTestL(&CCustomResolverCacheTest::TestCacheQueueFullPattern3L);
       
  1340 
       
  1341 	test.Next(_L("Basic TestCacheTimerAccuracyL"));
       
  1342 	DoBasicTestL(&CCustomResolverCacheTest::TestCacheTimerAccuracyL);
       
  1343 
       
  1344 	test.Next(_L("Basic TestTimestampUpdateOnCacheHitL"));
       
  1345 	DoBasicTestL(&CCustomResolverCacheTest::TestTimestampUpdateOnCacheHitL);
       
  1346 
       
  1347 	test.Next(_L("Basic TestSWIDisableRwResolverCachingL"));
       
  1348 	DoBasicTestL(&CCustomResolverCacheTest::TestSWIDisableRwResolverCachingL);
       
  1349 
       
  1350 	test.Next(_L("Basic TestBurDisableRwResolverCachingL"));
       
  1351 	DoBasicTestL(&CCustomResolverCacheTest::TestBurDisableRwResolverCachingL);
       
  1352 
       
  1353 	test.Next(_L("Basic TestClockChangeHasNoEffectOnCacheTimeoutL"));
       
  1354 	DoBasicTestL(&CCustomResolverCacheTest::TestClockChangeHasNoEffectOnCacheTimeoutL);
       
  1355 
       
  1356 	test.Next(_L("Basic TestCacheSizeZeroL"));
       
  1357 	DoBasicTestL(&CCustomResolverCacheTest::TestCacheSizeZeroL);
       
  1358 
       
  1359 	test.Next(_L("Basic TestCacheTimeoutZeroL"));
       
  1360 	DoBasicTestL(&CCustomResolverCacheTest::TestCacheTimeoutZeroL);
       
  1361 
       
  1362 	test.Next(_L("Basic TestResolverWithBadProxyTable"));
       
  1363 	DoBasicTestL(&CCustomResolverCacheTest::TestResolverWithBadProxyTable);
       
  1364 
       
  1365 	// Only run OOM on tests which do not involve rescan dir.
       
  1366 	test.Next(_L("OOM TestCacheQueueFullPattern3L"));
       
  1367 	DoOOMTestL(&CCustomResolverCacheTest::TestCacheQueueFullPattern3L);
       
  1368 
       
  1369 	test.Next(_L("OOM TestCacheTimerAccuracyL"));
       
  1370 	DoOOMTestL(&CCustomResolverCacheTest::TestCacheTimerAccuracyL);
       
  1371 
       
  1372 	test.Next(_L("OOM TestTimestampUpdateOnCacheHitL"));
       
  1373 	DoOOMTestL(&CCustomResolverCacheTest::TestTimestampUpdateOnCacheHitL);
       
  1374 
       
  1375 	// Do all tests affected by Lazy DLL unload last.
       
  1376 	test.Next(_L("Basic TestDeletingCachedResolverL"));
       
  1377 	DoBasicTestL(&CCustomResolverCacheTest::TestDeletingCachedResolverL);
       
  1378 	}
       
  1379 
       
  1380 static TInt KillEComServer()
       
  1381 	{
       
  1382 	//Need to ensure that the EComServer process is killed before even starting this test by using
       
  1383    	//the EComTestUtils library
       
  1384    	_LIT(KEComServerProcessName,"ecomserver");
       
  1385    	TRAPD(err, EComTestUtils::KillProcessL(KEComServerProcessName));
       
  1386    	return err;
       
  1387 	}
       
  1388 
       
  1389 GLDEF_C TInt E32Main()
       
  1390 	{
       
  1391 	__UHEAP_MARK;
       
  1392 
       
  1393 	beginningOfTest.UniversalTime();
       
  1394 
       
  1395 	test.Printf(_L("\n"));
       
  1396 	test.Title();
       
  1397 	test.Start( _L("Custom Resolver Cache") );
       
  1398 
       
  1399 
       
  1400 	TheTrapCleanup = CTrapCleanup::New();
       
  1401 	test(TheTrapCleanup != NULL);
       
  1402 
       
  1403 	// Connect the file server instance
       
  1404 	test(KErrNone == TheFs.Connect());
       
  1405 
       
  1406 	TheActiveScheduler = new CDerivedActiveScheduler;
       
  1407 	test(TheActiveScheduler != NULL);
       
  1408 	CActiveScheduler::Install(TheActiveScheduler);
       
  1409 
       
  1410 	TInt err = ::KillEComServer();
       
  1411 	test(err == KErrNotFound || err == KErrNone);
       
  1412 
       
  1413 	// Call the main tests
       
  1414 	TRAP(err, CCustomResolverCacheTest::RunAllTestsL());
       
  1415 	if (err != KErrNone) test.Printf(_L("RunAllTestsL() error, %d\n"), err);
       
  1416 	test(err == KErrNone);
       
  1417 
       
  1418 	// remove the RAMOnly files
       
  1419 	TRAP_IGNORE( WaitForLazyUnloadingL() );
       
  1420 	DeleteTestPlugin();
       
  1421 	User::After(KOneSecond * 3);
       
  1422 
       
  1423 	delete TheActiveScheduler;
       
  1424 	delete TheTrapCleanup;
       
  1425 
       
  1426 	TheFs.Close();
       
  1427 
       
  1428 	test.End();
       
  1429 	test.Close();
       
  1430 
       
  1431 	__UHEAP_MARKEND;
       
  1432 	return (KErrNone);
       
  1433 	}