Update contrib.
     1 // Copyright (c) 2005-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".
 
     8 // Initial Contributors:
 
     9 // Nokia Corporation - initial contribution.
 
    14 // This file contains code to test the EcomCachedDriveInfo class.
 
    20 #include <ecom/ecomerrorcodes.h>
 
    21 #include "EComPatchDataConstantv2.h"
 
    22 #include "DriveInfo.h"
 
    23 #include "EComInternalErrorCodes.h"
 
    24 #define UNUSED_VAR(a) (a = a)
 
    26 LOCAL_D RTest TheTest(_L("t_driveinfo"));
 
    28 static TInt IteratorPanicTest(TAny* aFuncCode);
 
    30 const TInt KPanicIndexOutOfBound = 133;
 
    31 _LIT(KTestFolder,			"C:\\TestTemp\\");
 
    33 enum TIteratorFunctionToTest
 
    35 	EIterFunctionDriveUnit,
 
    36 	EIterFunctionDriveNumber,
 
    37 	EIterFunctionIsReadOnlyInternal,
 
    38 	EIterFunctionIsRemovable
 
    41 class TDriveInfo_StateAccessor 
 
    44 	static CEComCachedDriveInfo* GetCachedDriveInfoL(RFs& aFs, TUint32 aDrvMask);
 
    45 	static void EComDrvFlagsL(TInt aDriveNum,
 
    47 							  const CEComCachedDriveInfo& aCachedDriveInfo);
 
    51 Because this class is friend of CEComCachedDriveInfo, it can call the
 
    52 private constructor of CEComCachedDriveInfo to make object instance
 
    53 with drive disabled mask different from the patchable constant.
 
    54 @param aFs Connected RFs session.
 
    55 @param aDrvMask The discovery disabled drive mask to pass to
 
    57 @return fully constructed CEComCachedDriveInfo. Caller owns the pointer.
 
    58 @leave KErrNoMemory if system out of memory.
 
    60 CEComCachedDriveInfo* TDriveInfo_StateAccessor::GetCachedDriveInfoL(
 
    64 	// Set this bool to false otherwise ConstructL will do nothing.
 
    65 	CEComCachedDriveInfo::iInitialized = EFalse;
 
    67 	CEComCachedDriveInfo* ptr = new (ELeave) CEComCachedDriveInfo();
 
    68 	CleanupStack::PushL(ptr);
 
    69 	ptr->ConstructL(aFs, aDrvMask);
 
    77 Retrieve the flag word stored by CEComCachedDriveInfo about a given drive.
 
    78 @param aDriveNum the drive of interest
 
    79 @param aDrvFlags output parameter to return the drive attributes
 
    80 @param aCachedDriveInfo the object instance to access.
 
    81 @leave KErrNotFound if no such drive
 
    83 void TDriveInfo_StateAccessor::EComDrvFlagsL(TInt aDriveNum,
 
    85 											const CEComCachedDriveInfo& aCachedDriveInfo)
 
    87 	for (TInt i = 0; i <= aCachedDriveInfo.iLastIndex; i++)
 
    89 		if (aCachedDriveInfo.iDriveAttr[i].iDrvNumber == aDriveNum)
 
    91 			aDrvFlags = aCachedDriveInfo.iDriveAttr[i].iFlags;
 
    96 	User::Leave(KErrNotFound);
 
    99 //Test macroses and functions
 
   100 LOCAL_C void CheckL(TInt aValue, TInt aLine)
 
   104 		TheTest(EFalse, aLine);
 
   107 #define TESTL(arg) ::CheckL((arg), __LINE__)
 
   110 /** Check CEComCachedDriveInfo has the correct attributes for the given drive
 
   111 and the iterator will return the drive if discovery is not disabled.
 
   113 LOCAL_C void VerifyDrvAttributeL(const TInt aDriveNum, 
 
   114 						  		TUint32 aDisableMask,
 
   115 							  	const CEComCachedDriveInfo& aCachedDriveInfo)
 
   117 	TEComCachedDriveInfoIterator iter(aCachedDriveInfo);
 
   119 	TDriveInfo driveInfo;
 
   120 	User::LeaveIfError(TheFs.Drive(driveInfo, aDriveNum));
 
   122 	if (0 == driveInfo.iDriveAtt)
 
   124 		// Drive not exist, i.e. drive letter not in-used
 
   126 		TESTL( !iter.SetPos(aDriveNum) );
 
   130 	TUint32 expectedAttr = 0;
 
   131 	if ((driveInfo.iDriveAtt & KDriveAttInternal) &&
 
   132 		(driveInfo.iMediaAtt & KMediaAttWriteProtected))
 
   134 		// Drive is ROnly internal which cannot be disabled.
 
   135 		expectedAttr = EEComDrvAttrReadOnlyInternal;
 
   139 		TUint32 drvBitMask = 1;
 
   140 		if ((drvBitMask << aDriveNum) & aDisableMask ||
 
   141 			driveInfo.iDriveAtt & KDriveAttSubsted ||
 
   142 			driveInfo.iDriveAtt & KDriveAttRemote)
 
   144 			expectedAttr |= EEComDrvAttrNoDiscovery;
 
   147 		if (driveInfo.iDriveAtt & KDriveAttRemovable)
 
   149 			expectedAttr |= EEComDrvAttrRemovable;
 
   152 		if (0 == (driveInfo.iDriveAtt & KDriveAttRom))
 
   154 			expectedAttr |= EEComDrvAttrWritable;
 
   158 	// Test iterator does not return disabled drives.
 
   159 	TBool found = EFalse;
 
   160 	for (iter.First(); iter.InRange() && !found; iter.Next())
 
   162 		if (iter.DriveNumber() == aDriveNum)
 
   168 	TBool expectedFound = !(expectedAttr & EEComDrvAttrNoDiscovery);
 
   169 	if (found != expectedFound)
 
   171 		TheTest.Printf(_L("Error drive %d, expected att 0x%X, iter found %d"), aDriveNum, expectedAttr, found);
 
   173 	TESTL(expectedFound == found);
 
   175 	// verify drive attributes
 
   176 	TUint32 actualAttr = 0;
 
   177 	TDriveInfo_StateAccessor::EComDrvFlagsL(aDriveNum, actualAttr,
 
   179 	if (actualAttr != expectedAttr)
 
   181 		TheTest.Printf(_L("Error drive %d, expected att 0x%X, got 0x%X"), aDriveNum, expectedAttr, actualAttr);
 
   183 	TESTL(actualAttr == expectedAttr);
 
   187 @SYMTestCaseID			SYSLIB-ECOM-UT-3536
 
   188 @SYMTestCaseDesc		Disable/enable each drive and verify CEComCachedDriveInfo
 
   189 	has correct attribute for each drive and the iterator will not return
 
   190 	drives that are disabled, subst or remote.
 
   191 @SYMTestPriority		High
 
   192 @SYMTestActions			Instantiate CEComCachedDriveInfo with each drive
 
   193 	disabled in turn. Verify the attribute and iterator operation on the drive.
 
   194 	Instantiate CEComCachedDriveInfo with all drive enable. Verify
 
   195 	attribute and iterator operation on each drive.
 
   196 @SYMTestExpectedResults	CEComCachedDriveInfo has the expected attributes for
 
   197 	each drive whethe the drive is enabled or disabled. The iterator will only
 
   198 	return the drive is the drive is enabled.
 
   201 LOCAL_C void DriveMaskTestL()
 
   203 	CEComCachedDriveInfo* cachedDriveInfo;
 
   205 	// Disable each drive in turn to check that disable works as expected.
 
   207 	for (i = EDriveA; i <= EDriveZ; i++)
 
   209 		TUint32 disableMask = 1 << i;
 
   210 		cachedDriveInfo = TDriveInfo_StateAccessor::GetCachedDriveInfoL(TheFs, disableMask);
 
   211 		CleanupStack::PushL(cachedDriveInfo);
 
   213 		// Check CEComCachedDriveInfo has the expected value.
 
   214 		VerifyDrvAttributeL(i, disableMask, *cachedDriveInfo);
 
   216 		// Test CEComCachedDriveInfo::DriveIsReadOnlyInternalL and 
 
   217 		// DriveIsRemovableL leaving. They should be used on drives that
 
   218 		// are known to be valid, e.g. drive extracted from the path
 
   219 		// of a discovered DLL.
 
   220 		// Since C: is disabled, CEComCachedDriveInfo will leave instead
 
   221 		// of answering true or false (because the answer is misleading).
 
   224 			TRAPD(err, cachedDriveInfo->DriveIsReadOnlyInternalL(i) );
 
   225 			TESTL(err == KEComErrDriveNotFound);
 
   227 			TRAP(err, cachedDriveInfo->DriveIsRemovableL(i) );
 
   228 			TESTL(err == KEComErrDriveNotFound);
 
   231 		CleanupStack::PopAndDestroy(cachedDriveInfo);
 
   235 	// Make sure the disable mask is zero.
 
   236 	TESTL(KDiscoveryDisabledDriveList == 0);
 
   238 	cachedDriveInfo = TDriveInfo_StateAccessor::GetCachedDriveInfoL(TheFs,0);
 
   239 	CleanupStack::PushL(cachedDriveInfo);
 
   241 	for (i = EDriveA; i < KMaxDrives; i++)
 
   243 		VerifyDrvAttributeL(i, 0, *cachedDriveInfo);
 
   246 	CleanupStack::PopAndDestroy(cachedDriveInfo);
 
   250 @SYMTestCaseID			SYSLIB-ECOM-UT-3537
 
   251 @SYMTestCaseDesc		Test the CEComCachedDriveInfo and its iterator classes
 
   252 	handles substituted drives correctly.
 
   253 @SYMTestPriority		High
 
   254 @SYMTestActions			Create a substituted drive, instantiate the cached drive info and verify that 
 
   255 						the sustitued drive is not in the valid drive list.
 
   256 @SYMTestExpectedResults	Substituted drive is not in the valid drive list.
 
   259 LOCAL_C void SubstitutedDriveTestL()
 
   261 	//Create c:\TestTemp folder
 
   262 	TInt err = TheFs.MkDir(KTestFolder);
 
   263 	//Create substituted drive L:, it maps to C:\TestTemp\ folder
 
   264 	err = TheFs.SetSubst(KTestFolder,EDriveL);
 
   265 	TESTL(err==KErrNone);
 
   267 	//Verify that L Drive is not in the valid list.	
 
   268 	CEComCachedDriveInfo* cachedDriveInfo =
 
   269 		TDriveInfo_StateAccessor::GetCachedDriveInfoL(TheFs,0);
 
   270 	CleanupStack::PushL(cachedDriveInfo);
 
   272 	VerifyDrvAttributeL(EDriveL, 0, *cachedDriveInfo);
 
   274 	CleanupStack::PopAndDestroy(cachedDriveInfo);
 
   277 	err = TheFs.SetSubst(KNullDesC, EDriveL);
 
   278 	TESTL(err==KErrNone);
 
   280 	err = TheFs.RmDir(KTestFolder);
 
   281 	TESTL(err==KErrNone);
 
   285 @SYMTestCaseID			SYSLIB-ECOM-UT-3539
 
   286 @SYMTestCaseDesc		Test the various methods exposed by TEComCachedDriveInfoIterator class.
 
   287 @SYMTestPriority		High
 
   288 @SYMTestActions			For each drive returned by the iterator, call all the
 
   290 @SYMTestExpectedResults	No leave or panic occur.
 
   293 LOCAL_C void ExerciseIterator()
 
   295 	CEComCachedDriveInfo* cachedDriveInfo = CEComCachedDriveInfo::NewL(TheFs);
 
   296 	CleanupStack::PushL(cachedDriveInfo);
 
   298 	TEComCachedDriveInfoIterator iter(*cachedDriveInfo);
 
   300 	for (iter.Last(); iter.InRange(); iter.Prev())
 
   302 		TDriveNumber drvNum = iter.DriveNumber();
 
   303 		TDriveUnit drvUnit = iter.DriveUnit();
 
   305 		// A trivial test just to use the returned objects.
 
   306 		TESTL(drvNum == drvUnit);
 
   308 		TBool b = iter.DriveIsReadOnlyInternal();
 
   311 		b = iter.DriveIsRemovable();
 
   315 	CleanupStack::PopAndDestroy(cachedDriveInfo);
 
   319 Intended Usage	: Capture the PANIC that occurs in the thread.
 
   320 @param			: aName The name to be assigned to this thread. 
 
   321 @param			: aFunction The function which causes the panic.
 
   323 LOCAL_C void ThreadPanicTest(const TDesC& aName,TThreadFunction aFunction)
 
   326 	TRequestStatus threadStatus;
 
   329 	jit=User::JustInTime();
 
   330 	User::SetJustInTime(EFalse);
 
   332 	for (TInt i = EIterFunctionDriveUnit; i <= EIterFunctionIsRemovable; i++)
 
   334 		TIteratorFunctionToTest func = static_cast<TIteratorFunctionToTest>(i);
 
   335 		TInt err=thread.Create(aName,aFunction,KDefaultStackSize,KMinHeapSize,KMinHeapSize, &func);
 
   336 		TESTL(err==KErrNone);
 
   338 		thread.Logon(threadStatus);
 
   340 		User::WaitForRequest(threadStatus);
 
   342 		//Now check why the thread Exit
 
   343 		TExitType exitType = thread.ExitType();
 
   344 		TInt exitReason = thread.ExitReason();
 
   345 		TheTest.Printf(_L("PanicTest: exitType %d, reason %d\n"), exitType, exitReason);
 
   347 		TESTL(exitType == EExitPanic);
 
   348 		TESTL(exitReason == KPanicIndexOutOfBound);
 
   352 	User::SetJustInTime(jit);
 
   356 @SYMTestCaseID			SYSLIB-ECOM-UT-3540
 
   357 @SYMTestCaseDesc		Test the TEComCachedDriveInfoIterator class will panic if object instance of this class access out of bound elements.
 
   358 @SYMTestPriority		High
 
   359 @SYMTestActions			Cause the iterator to panic by accessing out of range
 
   361 @SYMTestExpectedResults	Panic occur.
 
   364 LOCAL_C void DoIteratorPanicTestL(TIteratorFunctionToTest aFuncCode)
 
   366 	CEComCachedDriveInfo* cachedDriveInfo = CEComCachedDriveInfo::NewL(TheFs);
 
   367 	CleanupStack::PushL(cachedDriveInfo);
 
   369 	TEComCachedDriveInfoIterator iter(*cachedDriveInfo);
 
   370 	// Run the iterator out of range.
 
   371 	for (iter.Last(); iter.InRange(); iter.Prev())
 
   375 	// Access the getter function to trigger panic.
 
   378 		case EIterFunctionDriveUnit:
 
   380 			TDriveUnit d = iter.DriveUnit();
 
   383 		case EIterFunctionDriveNumber:
 
   385 			TDriveNumber d = iter.DriveNumber();
 
   388 		case EIterFunctionIsReadOnlyInternal:
 
   390 			TBool f = iter.DriveIsReadOnlyInternal();
 
   393 		case EIterFunctionIsRemovable:
 
   395 			TBool f = iter.DriveIsRemovable();
 
   399 			// do nothing and the test will fail.
 
   403 	CleanupStack::PopAndDestroy(cachedDriveInfo);
 
   407 @SYMTestCaseID			SYSLIB-ECOM-CT-1485
 
   408 @SYMTestCaseDesc		Tests EcomCachedDriveInfo class.
 
   409 @SYMTestPriority			High
 
   410 @SYMTestActions			Test the various methods exposed by EcomCachedDriveInfo,
 
   411 						 ensuring that the returned values are correct.
 
   412 @SYMTestExpectedResults	The test must not fail.
 
   415 LOCAL_C void SystemDriveTestL()
 
   417 	CEComCachedDriveInfo* cachedDriveInfo = CEComCachedDriveInfo::NewL(TheFs);
 
   418 	CleanupStack::PushL(cachedDriveInfo);
 
   420 	TDriveNumber driveSys = RFs::GetSystemDrive();
 
   421 	TESTL( !cachedDriveInfo->DriveIsReadOnlyInternalL(driveSys) );
 
   422 	TESTL(  cachedDriveInfo->DriveIsWritableL(driveSys) );
 
   424 	// The old EcomCachedDriveInfo class has DriveIsRemoteL and
 
   425 	// DriveIsSubstL methods. To verify that system drive is neither
 
   426 	// remote nor subst, use TEComCachedDriveInfoIterator::SetPos().
 
   428 	TEComCachedDriveInfoIterator iter(*cachedDriveInfo);
 
   429 	TESTL( iter.SetPos(driveSys) );
 
   431 	// Test Z: drive property
 
   432 	TESTL( cachedDriveInfo->DriveIsReadOnlyInternalL(EDriveZ) );
 
   434 	CleanupStack::PopAndDestroy(cachedDriveInfo);
 
   437 /** Setup the TRAP harness to invoke DoIteratorPanicTestL
 
   439 TInt IteratorPanicTest(TAny* aFuncCode)
 
   441 	CTrapCleanup* threadcleanup = CTrapCleanup::New();
 
   442 	TIteratorFunctionToTest* funcCode = static_cast<TIteratorFunctionToTest*>(aFuncCode);
 
   443 	TRAPD(ret, DoIteratorPanicTestL(*funcCode)); 
 
   445 	delete threadcleanup;
 
   449 typedef void (*ClassFuncPtrL) (void);
 
   451 Test under OOM conditions.
 
   452 This is a wrapper function to call all test functions.
 
   453 @param	aTestFunctionL	 Pointer to test function.
 
   454 @param		aTestDesc test function name
 
   456 LOCAL_C void DoOOMTestL(ClassFuncPtrL aTestFunctionL, const TDesC& aTestDesc)
 
   458 	TheTest.Next(aTestDesc);
 
   465 		// find out the number of open handles
 
   466 		TInt startProcessHandleCount;
 
   467 		TInt startThreadHandleCount;
 
   468 		RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);
 
   470 		__UHEAP_SETFAIL(RHeap::EDeterministic, ++tryCount);
 
   472 		TRAP(err, aTestFunctionL());
 
   474 		__UHEAP_SETFAIL(RHeap::ENone, 0);
 
   476 		// check that no handles have leaked
 
   477 		TInt endProcessHandleCount;
 
   478 		TInt endThreadHandleCount; 
 
   479 		RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);
 
   480 		TESTL(startProcessHandleCount == endProcessHandleCount);
 
   481 		TESTL(startThreadHandleCount  == endThreadHandleCount);
 
   484 		} while(err == KErrNoMemory);
 
   486  	TESTL(err==KErrNone);
 
   487 	TheTest.Printf(_L("- succeeded at heap failure rate of %i\n"), tryCount);
 
   491 Wrapper function to call all test functions
 
   492 @param		aTestFunctionL pointer to test function
 
   493 @param		aTestDesc test function name
 
   495 LOCAL_C void DoBasicTestL(ClassFuncPtrL aTestFunctionL, const TDesC& aTestDesc)
 
   497 	TheTest.Next(aTestDesc);
 
   499   	// find out the number of open handles
 
   500 	TInt startProcessHandleCount;
 
   501 	TInt startThreadHandleCount;
 
   502 	RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);
 
   506 	// check that no handles have leaked
 
   507 	TInt endProcessHandleCount;
 
   508 	TInt endThreadHandleCount;
 
   509 	RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);
 
   511 	TESTL(startProcessHandleCount == endProcessHandleCount);
 
   512 	TESTL(startThreadHandleCount  == endThreadHandleCount);
 
   517 LOCAL_C void DoTestsL()
 
   521 	User::LeaveIfError(TheFs.Connect());
 
   522 	CleanupClosePushL(TheFs);
 
   525 	DoBasicTestL(&DriveMaskTestL, _L("Drive Mask Test."));
 
   526 	DoBasicTestL(&SubstitutedDriveTestL, _L("Substituted Drive Test."));
 
   527 	DoBasicTestL(&ExerciseIterator, _L("Getter Test."));
 
   528 	DoBasicTestL(&SystemDriveTestL, _L("System Drive Test."));
 
   531 	ThreadPanicTest(_L("Iterator Panic Testing"),IteratorPanicTest);
 
   534 	DoOOMTestL(&DriveMaskTestL, _L("OOM Test for Drive Mask Test."));
 
   535 	DoOOMTestL(&ExerciseIterator, _L("OOM Test for Getter."));
 
   536 	DoOOMTestL(&SystemDriveTestL, _L("OOM Test for System Drive Test."));
 
   538 	CleanupStack::PopAndDestroy();
 
   544 GLDEF_C TInt E32Main()
 
   549 	TheTest.Start(_L("Start Drive Info Tests."));
 
   551 	User::LeaveIfError (TheFs.Connect ());
 
   553 	CTrapCleanup* cleanup = CTrapCleanup::New();
 
   554 	CActiveScheduler* scheduler = new(ELeave)CActiveScheduler;
 
   555 	CActiveScheduler::Install(scheduler);
 
   557 	TRAPD(err,DoTestsL());
 
   558 	TESTL(err==KErrNone);