os/ossrv/lowlevellibsandfws/pluginfw/Framework/DriveInfoTest/t_driveinfo.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/lowlevellibsandfws/pluginfw/Framework/DriveInfoTest/t_driveinfo.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,570 @@
     1.4 +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// This file contains code to test the EcomCachedDriveInfo class.
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include <e32test.h>
    1.22 +#include <f32file.h>
    1.23 +#include <ecom/ecomerrorcodes.h>
    1.24 +#include "EComPatchDataConstantv2.h"
    1.25 +#include "DriveInfo.h"
    1.26 +#include "EComInternalErrorCodes.h"
    1.27 +#define UNUSED_VAR(a) (a = a)
    1.28 +
    1.29 +LOCAL_D RTest TheTest(_L("t_driveinfo"));
    1.30 +LOCAL_D RFs	TheFs;
    1.31 +static TInt IteratorPanicTest(TAny* aFuncCode);
    1.32 +
    1.33 +const TInt KPanicIndexOutOfBound = 133;
    1.34 +_LIT(KTestFolder,			"C:\\TestTemp\\");
    1.35 +
    1.36 +enum TIteratorFunctionToTest
    1.37 +	{
    1.38 +	EIterFunctionDriveUnit,
    1.39 +	EIterFunctionDriveNumber,
    1.40 +	EIterFunctionIsReadOnlyInternal,
    1.41 +	EIterFunctionIsRemovable
    1.42 +	};
    1.43 +
    1.44 +class TDriveInfo_StateAccessor 
    1.45 +	{
    1.46 +public:
    1.47 +	static CEComCachedDriveInfo* GetCachedDriveInfoL(RFs& aFs, TUint32 aDrvMask);
    1.48 +	static void EComDrvFlagsL(TInt aDriveNum,
    1.49 +							  TUint32& aDrvFlags,
    1.50 +							  const CEComCachedDriveInfo& aCachedDriveInfo);
    1.51 +	};
    1.52 +
    1.53 +/**
    1.54 +Because this class is friend of CEComCachedDriveInfo, it can call the
    1.55 +private constructor of CEComCachedDriveInfo to make object instance
    1.56 +with drive disabled mask different from the patchable constant.
    1.57 +@param aFs Connected RFs session.
    1.58 +@param aDrvMask The discovery disabled drive mask to pass to
    1.59 +	CEComCachedDriveInfo.
    1.60 +@return fully constructed CEComCachedDriveInfo. Caller owns the pointer.
    1.61 +@leave KErrNoMemory if system out of memory.
    1.62 +*/
    1.63 +CEComCachedDriveInfo* TDriveInfo_StateAccessor::GetCachedDriveInfoL(
    1.64 +	RFs&	aFs,
    1.65 +	TUint32 aDrvMask)
    1.66 +	{
    1.67 +	// Set this bool to false otherwise ConstructL will do nothing.
    1.68 +	CEComCachedDriveInfo::iInitialized = EFalse;
    1.69 +
    1.70 +	CEComCachedDriveInfo* ptr = new (ELeave) CEComCachedDriveInfo();
    1.71 +	CleanupStack::PushL(ptr);
    1.72 +	ptr->ConstructL(aFs, aDrvMask);
    1.73 +	CleanupStack::Pop();
    1.74 +	return ptr;
    1.75 +	}
    1.76 +
    1.77 +/**
    1.78 +static method
    1.79 +
    1.80 +Retrieve the flag word stored by CEComCachedDriveInfo about a given drive.
    1.81 +@param aDriveNum the drive of interest
    1.82 +@param aDrvFlags output parameter to return the drive attributes
    1.83 +@param aCachedDriveInfo the object instance to access.
    1.84 +@leave KErrNotFound if no such drive
    1.85 +*/
    1.86 +void TDriveInfo_StateAccessor::EComDrvFlagsL(TInt aDriveNum,
    1.87 +											TUint32& aDrvFlags,
    1.88 +											const CEComCachedDriveInfo& aCachedDriveInfo)
    1.89 +	{
    1.90 +	for (TInt i = 0; i <= aCachedDriveInfo.iLastIndex; i++)
    1.91 +		{
    1.92 +		if (aCachedDriveInfo.iDriveAttr[i].iDrvNumber == aDriveNum)
    1.93 +			{
    1.94 +			aDrvFlags = aCachedDriveInfo.iDriveAttr[i].iFlags;
    1.95 +			return;
    1.96 +			}
    1.97 +		}
    1.98 +
    1.99 +	User::Leave(KErrNotFound);
   1.100 +	}
   1.101 +
   1.102 +//Test macroses and functions
   1.103 +LOCAL_C void CheckL(TInt aValue, TInt aLine)
   1.104 +	{
   1.105 +	if(!aValue)
   1.106 +		{
   1.107 +		TheTest(EFalse, aLine);
   1.108 +		}
   1.109 +	}
   1.110 +#define TESTL(arg) ::CheckL((arg), __LINE__)
   1.111 +
   1.112 +
   1.113 +/** Check CEComCachedDriveInfo has the correct attributes for the given drive
   1.114 +and the iterator will return the drive if discovery is not disabled.
   1.115 +*/
   1.116 +LOCAL_C void VerifyDrvAttributeL(const TInt aDriveNum, 
   1.117 +						  		TUint32 aDisableMask,
   1.118 +							  	const CEComCachedDriveInfo& aCachedDriveInfo)
   1.119 +	{
   1.120 +	TEComCachedDriveInfoIterator iter(aCachedDriveInfo);
   1.121 +
   1.122 +	TDriveInfo driveInfo;
   1.123 +	User::LeaveIfError(TheFs.Drive(driveInfo, aDriveNum));
   1.124 +
   1.125 +	if (0 == driveInfo.iDriveAtt)
   1.126 +		{
   1.127 +		// Drive not exist, i.e. drive letter not in-used
   1.128 +
   1.129 +		TESTL( !iter.SetPos(aDriveNum) );
   1.130 +		return;
   1.131 +		}
   1.132 +
   1.133 +	TUint32 expectedAttr = 0;
   1.134 +	if ((driveInfo.iDriveAtt & KDriveAttInternal) &&
   1.135 +		(driveInfo.iMediaAtt & KMediaAttWriteProtected))
   1.136 +		{
   1.137 +		// Drive is ROnly internal which cannot be disabled.
   1.138 +		expectedAttr = EEComDrvAttrReadOnlyInternal;
   1.139 +		}
   1.140 +	else
   1.141 +		{
   1.142 +		TUint32 drvBitMask = 1;
   1.143 +		if ((drvBitMask << aDriveNum) & aDisableMask ||
   1.144 +			driveInfo.iDriveAtt & KDriveAttSubsted ||
   1.145 +			driveInfo.iDriveAtt & KDriveAttRemote)
   1.146 +			{
   1.147 +			expectedAttr |= EEComDrvAttrNoDiscovery;
   1.148 +			}
   1.149 +		
   1.150 +		if (driveInfo.iDriveAtt & KDriveAttRemovable)
   1.151 +			{
   1.152 +			expectedAttr |= EEComDrvAttrRemovable;
   1.153 +			}
   1.154 +		
   1.155 +		if (0 == (driveInfo.iDriveAtt & KDriveAttRom))
   1.156 +			{
   1.157 +			expectedAttr |= EEComDrvAttrWritable;
   1.158 +			}
   1.159 +		}
   1.160 +
   1.161 +	// Test iterator does not return disabled drives.
   1.162 +	TBool found = EFalse;
   1.163 +	for (iter.First(); iter.InRange() && !found; iter.Next())
   1.164 +		{
   1.165 +		if (iter.DriveNumber() == aDriveNum)
   1.166 +			{
   1.167 +			found = ETrue;
   1.168 +			}
   1.169 +		}
   1.170 +
   1.171 +	TBool expectedFound = !(expectedAttr & EEComDrvAttrNoDiscovery);
   1.172 +	if (found != expectedFound)
   1.173 +		{
   1.174 +		TheTest.Printf(_L("Error drive %d, expected att 0x%X, iter found %d"), aDriveNum, expectedAttr, found);
   1.175 +		}
   1.176 +	TESTL(expectedFound == found);
   1.177 +
   1.178 +	// verify drive attributes
   1.179 +	TUint32 actualAttr = 0;
   1.180 +	TDriveInfo_StateAccessor::EComDrvFlagsL(aDriveNum, actualAttr,
   1.181 +		aCachedDriveInfo);
   1.182 +	if (actualAttr != expectedAttr)
   1.183 +		{
   1.184 +		TheTest.Printf(_L("Error drive %d, expected att 0x%X, got 0x%X"), aDriveNum, expectedAttr, actualAttr);
   1.185 +		}
   1.186 +	TESTL(actualAttr == expectedAttr);
   1.187 +	}
   1.188 +
   1.189 +/**
   1.190 +@SYMTestCaseID			SYSLIB-ECOM-UT-3536
   1.191 +@SYMTestCaseDesc		Disable/enable each drive and verify CEComCachedDriveInfo
   1.192 +	has correct attribute for each drive and the iterator will not return
   1.193 +	drives that are disabled, subst or remote.
   1.194 +@SYMTestPriority		High
   1.195 +@SYMTestActions			Instantiate CEComCachedDriveInfo with each drive
   1.196 +	disabled in turn. Verify the attribute and iterator operation on the drive.
   1.197 +	Instantiate CEComCachedDriveInfo with all drive enable. Verify
   1.198 +	attribute and iterator operation on each drive.
   1.199 +@SYMTestExpectedResults	CEComCachedDriveInfo has the expected attributes for
   1.200 +	each drive whethe the drive is enabled or disabled. The iterator will only
   1.201 +	return the drive is the drive is enabled.
   1.202 +@SYMCR					CR1049
   1.203 +*/
   1.204 +LOCAL_C void DriveMaskTestL()
   1.205 +	{
   1.206 +	CEComCachedDriveInfo* cachedDriveInfo;
   1.207 +
   1.208 +	// Disable each drive in turn to check that disable works as expected.
   1.209 +	TInt i;
   1.210 +	for (i = EDriveA; i <= EDriveZ; i++)
   1.211 +		{
   1.212 +		TUint32 disableMask = 1 << i;
   1.213 +		cachedDriveInfo = TDriveInfo_StateAccessor::GetCachedDriveInfoL(TheFs, disableMask);
   1.214 +		CleanupStack::PushL(cachedDriveInfo);
   1.215 +
   1.216 +		// Check CEComCachedDriveInfo has the expected value.
   1.217 +		VerifyDrvAttributeL(i, disableMask, *cachedDriveInfo);
   1.218 +
   1.219 +		// Test CEComCachedDriveInfo::DriveIsReadOnlyInternalL and 
   1.220 +		// DriveIsRemovableL leaving. They should be used on drives that
   1.221 +		// are known to be valid, e.g. drive extracted from the path
   1.222 +		// of a discovered DLL.
   1.223 +		// Since C: is disabled, CEComCachedDriveInfo will leave instead
   1.224 +		// of answering true or false (because the answer is misleading).
   1.225 +		if (i == EDriveC)
   1.226 +			{
   1.227 +			TRAPD(err, cachedDriveInfo->DriveIsReadOnlyInternalL(i) );
   1.228 +			TESTL(err == KEComErrDriveNotFound);
   1.229 +
   1.230 +			TRAP(err, cachedDriveInfo->DriveIsRemovableL(i) );
   1.231 +			TESTL(err == KEComErrDriveNotFound);
   1.232 +			}
   1.233 +
   1.234 +		CleanupStack::PopAndDestroy(cachedDriveInfo);
   1.235 +		}
   1.236 +
   1.237 +	// Test enable case.
   1.238 +	// Make sure the disable mask is zero.
   1.239 +	TESTL(KDiscoveryDisabledDriveList == 0);
   1.240 +
   1.241 +	cachedDriveInfo = TDriveInfo_StateAccessor::GetCachedDriveInfoL(TheFs,0);
   1.242 +	CleanupStack::PushL(cachedDriveInfo);
   1.243 +
   1.244 +	for (i = EDriveA; i < KMaxDrives; i++)
   1.245 +		{
   1.246 +		VerifyDrvAttributeL(i, 0, *cachedDriveInfo);
   1.247 +		}
   1.248 +
   1.249 +	CleanupStack::PopAndDestroy(cachedDriveInfo);
   1.250 +	}
   1.251 +
   1.252 +/**
   1.253 +@SYMTestCaseID			SYSLIB-ECOM-UT-3537
   1.254 +@SYMTestCaseDesc		Test the CEComCachedDriveInfo and its iterator classes
   1.255 +	handles substituted drives correctly.
   1.256 +@SYMTestPriority		High
   1.257 +@SYMTestActions			Create a substituted drive, instantiate the cached drive info and verify that 
   1.258 +						the sustitued drive is not in the valid drive list.
   1.259 +@SYMTestExpectedResults	Substituted drive is not in the valid drive list.
   1.260 +@SYMCR					CR1049
   1.261 +*/
   1.262 +LOCAL_C void SubstitutedDriveTestL()
   1.263 +	{
   1.264 +	//Create c:\TestTemp folder
   1.265 +	TInt err = TheFs.MkDir(KTestFolder);
   1.266 +	//Create substituted drive L:, it maps to C:\TestTemp\ folder
   1.267 +	err = TheFs.SetSubst(KTestFolder,EDriveL);
   1.268 +	TESTL(err==KErrNone);
   1.269 +
   1.270 +	//Verify that L Drive is not in the valid list.	
   1.271 +	CEComCachedDriveInfo* cachedDriveInfo =
   1.272 +		TDriveInfo_StateAccessor::GetCachedDriveInfoL(TheFs,0);
   1.273 +	CleanupStack::PushL(cachedDriveInfo);
   1.274 +
   1.275 +	VerifyDrvAttributeL(EDriveL, 0, *cachedDriveInfo);
   1.276 +
   1.277 +	CleanupStack::PopAndDestroy(cachedDriveInfo);
   1.278 +
   1.279 +	// undo subst
   1.280 +	err = TheFs.SetSubst(KNullDesC, EDriveL);
   1.281 +	TESTL(err==KErrNone);
   1.282 +
   1.283 +	err = TheFs.RmDir(KTestFolder);
   1.284 +	TESTL(err==KErrNone);
   1.285 +	}
   1.286 +
   1.287 +/**
   1.288 +@SYMTestCaseID			SYSLIB-ECOM-UT-3539
   1.289 +@SYMTestCaseDesc		Test the various methods exposed by TEComCachedDriveInfoIterator class.
   1.290 +@SYMTestPriority		High
   1.291 +@SYMTestActions			For each drive returned by the iterator, call all the
   1.292 +	getter methods.
   1.293 +@SYMTestExpectedResults	No leave or panic occur.
   1.294 +@SYMCR					CR1049
   1.295 +*/
   1.296 +LOCAL_C void ExerciseIterator()
   1.297 +	{
   1.298 +	CEComCachedDriveInfo* cachedDriveInfo = CEComCachedDriveInfo::NewL(TheFs);
   1.299 +	CleanupStack::PushL(cachedDriveInfo);
   1.300 +
   1.301 +	TEComCachedDriveInfoIterator iter(*cachedDriveInfo);
   1.302 +
   1.303 +	for (iter.Last(); iter.InRange(); iter.Prev())
   1.304 +		{
   1.305 +		TDriveNumber drvNum = iter.DriveNumber();
   1.306 +		TDriveUnit drvUnit = iter.DriveUnit();
   1.307 +
   1.308 +		// A trivial test just to use the returned objects.
   1.309 +		TESTL(drvNum == drvUnit);
   1.310 +
   1.311 +		TBool b = iter.DriveIsReadOnlyInternal();
   1.312 +		UNUSED_VAR(b);
   1.313 +
   1.314 +		b = iter.DriveIsRemovable();
   1.315 +		UNUSED_VAR(b);
   1.316 +		}
   1.317 +
   1.318 +	CleanupStack::PopAndDestroy(cachedDriveInfo);
   1.319 +	}
   1.320 +
   1.321 +/**
   1.322 +Intended Usage	: Capture the PANIC that occurs in the thread.
   1.323 +@param			: aName The name to be assigned to this thread. 
   1.324 +@param			: aFunction The function which causes the panic.
   1.325 +*/
   1.326 +LOCAL_C void ThreadPanicTest(const TDesC& aName,TThreadFunction aFunction)
   1.327 +	{
   1.328 +	TheTest.Next(aName);
   1.329 +	TRequestStatus threadStatus;
   1.330 +	RThread thread;
   1.331 +	TBool jit;
   1.332 +	jit=User::JustInTime();
   1.333 +	User::SetJustInTime(EFalse);
   1.334 +
   1.335 +	for (TInt i = EIterFunctionDriveUnit; i <= EIterFunctionIsRemovable; i++)
   1.336 +		{
   1.337 +		TIteratorFunctionToTest func = static_cast<TIteratorFunctionToTest>(i);
   1.338 +		TInt err=thread.Create(aName,aFunction,KDefaultStackSize,KMinHeapSize,KMinHeapSize, &func);
   1.339 +		TESTL(err==KErrNone);
   1.340 +	
   1.341 +		thread.Logon(threadStatus);
   1.342 +		thread.Resume();
   1.343 +		User::WaitForRequest(threadStatus);
   1.344 +
   1.345 +		//Now check why the thread Exit
   1.346 +		TExitType exitType = thread.ExitType();
   1.347 +		TInt exitReason = thread.ExitReason();
   1.348 +		TheTest.Printf(_L("PanicTest: exitType %d, reason %d\n"), exitType, exitReason);
   1.349 +
   1.350 +		TESTL(exitType == EExitPanic);
   1.351 +		TESTL(exitReason == KPanicIndexOutOfBound);
   1.352 +		thread.Close();
   1.353 +		}
   1.354 +
   1.355 +	User::SetJustInTime(jit);
   1.356 +	}
   1.357 +
   1.358 +/**
   1.359 +@SYMTestCaseID			SYSLIB-ECOM-UT-3540
   1.360 +@SYMTestCaseDesc		Test the TEComCachedDriveInfoIterator class will panic if object instance of this class access out of bound elements.
   1.361 +@SYMTestPriority		High
   1.362 +@SYMTestActions			Cause the iterator to panic by accessing out of range
   1.363 +	cell.
   1.364 +@SYMTestExpectedResults	Panic occur.
   1.365 +@SYMCR					CR1049
   1.366 +*/
   1.367 +LOCAL_C void DoIteratorPanicTestL(TIteratorFunctionToTest aFuncCode)
   1.368 +	{
   1.369 +	CEComCachedDriveInfo* cachedDriveInfo = CEComCachedDriveInfo::NewL(TheFs);
   1.370 +	CleanupStack::PushL(cachedDriveInfo);
   1.371 +
   1.372 +	TEComCachedDriveInfoIterator iter(*cachedDriveInfo);
   1.373 +	// Run the iterator out of range.
   1.374 +	for (iter.Last(); iter.InRange(); iter.Prev())
   1.375 +		{
   1.376 +		}
   1.377 +
   1.378 +	// Access the getter function to trigger panic.
   1.379 +	switch (aFuncCode)
   1.380 +		{
   1.381 +		case EIterFunctionDriveUnit:
   1.382 +			{
   1.383 +			TDriveUnit d = iter.DriveUnit();
   1.384 +			break;
   1.385 +			}
   1.386 +		case EIterFunctionDriveNumber:
   1.387 +			{
   1.388 +			TDriveNumber d = iter.DriveNumber();
   1.389 +			break;
   1.390 +			}
   1.391 +		case EIterFunctionIsReadOnlyInternal:
   1.392 +			{
   1.393 +			TBool f = iter.DriveIsReadOnlyInternal();
   1.394 +			break;
   1.395 +			}
   1.396 +		case EIterFunctionIsRemovable:
   1.397 +			{
   1.398 +			TBool f = iter.DriveIsRemovable();
   1.399 +			break;
   1.400 +			}
   1.401 +		default:
   1.402 +			// do nothing and the test will fail.
   1.403 +			break;
   1.404 +		}
   1.405 +
   1.406 +	CleanupStack::PopAndDestroy(cachedDriveInfo);
   1.407 +	}
   1.408 +
   1.409 +/**
   1.410 +@SYMTestCaseID			SYSLIB-ECOM-CT-1485
   1.411 +@SYMTestCaseDesc		Tests EcomCachedDriveInfo class.
   1.412 +@SYMTestPriority			High
   1.413 +@SYMTestActions			Test the various methods exposed by EcomCachedDriveInfo,
   1.414 +						 ensuring that the returned values are correct.
   1.415 +@SYMTestExpectedResults	The test must not fail.
   1.416 +@SYMDEF				 DEF073919
   1.417 +*/
   1.418 +LOCAL_C void SystemDriveTestL()
   1.419 +	{
   1.420 +	CEComCachedDriveInfo* cachedDriveInfo = CEComCachedDriveInfo::NewL(TheFs);
   1.421 +	CleanupStack::PushL(cachedDriveInfo);
   1.422 +
   1.423 +	TDriveNumber driveSys = RFs::GetSystemDrive();
   1.424 +	TESTL( !cachedDriveInfo->DriveIsReadOnlyInternalL(driveSys) );
   1.425 +	TESTL(  cachedDriveInfo->DriveIsWritableL(driveSys) );
   1.426 +
   1.427 +	// The old EcomCachedDriveInfo class has DriveIsRemoteL and
   1.428 +	// DriveIsSubstL methods. To verify that system drive is neither
   1.429 +	// remote nor subst, use TEComCachedDriveInfoIterator::SetPos().
   1.430 +	
   1.431 +	TEComCachedDriveInfoIterator iter(*cachedDriveInfo);
   1.432 +	TESTL( iter.SetPos(driveSys) );
   1.433 +
   1.434 +	// Test Z: drive property
   1.435 +	TESTL( cachedDriveInfo->DriveIsReadOnlyInternalL(EDriveZ) );
   1.436 +	
   1.437 +	CleanupStack::PopAndDestroy(cachedDriveInfo);
   1.438 +	}
   1.439 +
   1.440 +/** Setup the TRAP harness to invoke DoIteratorPanicTestL
   1.441 +*/
   1.442 +TInt IteratorPanicTest(TAny* aFuncCode)
   1.443 +	{
   1.444 +	CTrapCleanup* threadcleanup = CTrapCleanup::New();
   1.445 +	TIteratorFunctionToTest* funcCode = static_cast<TIteratorFunctionToTest*>(aFuncCode);
   1.446 +	TRAPD(ret, DoIteratorPanicTestL(*funcCode)); 
   1.447 +
   1.448 +	delete threadcleanup;
   1.449 +	return ret;
   1.450 +	}
   1.451 +
   1.452 +typedef void (*ClassFuncPtrL) (void);
   1.453 +/**
   1.454 +Test under OOM conditions.
   1.455 +This is a wrapper function to call all test functions.
   1.456 +@param	aTestFunctionL	 Pointer to test function.
   1.457 +@param		aTestDesc test function name
   1.458 +*/
   1.459 +LOCAL_C void DoOOMTestL(ClassFuncPtrL aTestFunctionL, const TDesC& aTestDesc)
   1.460 +	{
   1.461 +	TheTest.Next(aTestDesc);
   1.462 +	TInt err = KErrNone;
   1.463 +	TInt tryCount = 0;
   1.464 +	do
   1.465 +		{
   1.466 +		__UHEAP_MARK;
   1.467 +
   1.468 +		// find out the number of open handles
   1.469 +		TInt startProcessHandleCount;
   1.470 +		TInt startThreadHandleCount;
   1.471 +		RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);
   1.472 +
   1.473 +		__UHEAP_SETFAIL(RHeap::EDeterministic, ++tryCount);
   1.474 +	
   1.475 +		TRAP(err, aTestFunctionL());
   1.476 +
   1.477 +		__UHEAP_SETFAIL(RHeap::ENone, 0);
   1.478 +		
   1.479 +		// check that no handles have leaked
   1.480 +		TInt endProcessHandleCount;
   1.481 +		TInt endThreadHandleCount; 
   1.482 +		RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);
   1.483 +		TESTL(startProcessHandleCount == endProcessHandleCount);
   1.484 +		TESTL(startThreadHandleCount  == endThreadHandleCount);
   1.485 +
   1.486 +		__UHEAP_MARKEND;
   1.487 +		} while(err == KErrNoMemory);
   1.488 +
   1.489 + 	TESTL(err==KErrNone);
   1.490 +	TheTest.Printf(_L("- succeeded at heap failure rate of %i\n"), tryCount);
   1.491 +	}
   1.492 +
   1.493 +/**
   1.494 +Wrapper function to call all test functions
   1.495 +@param		aTestFunctionL pointer to test function
   1.496 +@param		aTestDesc test function name
   1.497 +*/
   1.498 +LOCAL_C void DoBasicTestL(ClassFuncPtrL aTestFunctionL, const TDesC& aTestDesc)
   1.499 +	{
   1.500 +	TheTest.Next(aTestDesc);
   1.501 +	__UHEAP_MARK;
   1.502 +  	// find out the number of open handles
   1.503 +	TInt startProcessHandleCount;
   1.504 +	TInt startThreadHandleCount;
   1.505 +	RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);
   1.506 +
   1.507 +	aTestFunctionL();
   1.508 +	
   1.509 +	// check that no handles have leaked
   1.510 +	TInt endProcessHandleCount;
   1.511 +	TInt endThreadHandleCount;
   1.512 +	RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);
   1.513 +
   1.514 +	TESTL(startProcessHandleCount == endProcessHandleCount);
   1.515 +	TESTL(startThreadHandleCount  == endThreadHandleCount);
   1.516 +
   1.517 +	__UHEAP_MARKEND;
   1.518 +	}
   1.519 +	
   1.520 +LOCAL_C void DoTestsL()
   1.521 +	{
   1.522 +	__UHEAP_MARK;
   1.523 +
   1.524 +	User::LeaveIfError(TheFs.Connect());
   1.525 +	CleanupClosePushL(TheFs);
   1.526 +
   1.527 +	// normal tests
   1.528 +	DoBasicTestL(&DriveMaskTestL, _L("Drive Mask Test."));
   1.529 +	DoBasicTestL(&SubstitutedDriveTestL, _L("Substituted Drive Test."));
   1.530 +	DoBasicTestL(&ExerciseIterator, _L("Getter Test."));
   1.531 +	DoBasicTestL(&SystemDriveTestL, _L("System Drive Test."));
   1.532 +
   1.533 +	// panic tests
   1.534 +	ThreadPanicTest(_L("Iterator Panic Testing"),IteratorPanicTest);
   1.535 +	
   1.536 +	// OOM tests
   1.537 +	DoOOMTestL(&DriveMaskTestL, _L("OOM Test for Drive Mask Test."));
   1.538 +	DoOOMTestL(&ExerciseIterator, _L("OOM Test for Getter."));
   1.539 +	DoOOMTestL(&SystemDriveTestL, _L("OOM Test for System Drive Test."));
   1.540 +	
   1.541 +	CleanupStack::PopAndDestroy();
   1.542 +	
   1.543 +	__UHEAP_MARKEND;
   1.544 +	}
   1.545 +
   1.546 +
   1.547 +GLDEF_C TInt E32Main()
   1.548 +	{
   1.549 +	__UHEAP_MARK;
   1.550 +		
   1.551 +	TheTest.Title();
   1.552 +	TheTest.Start(_L("Start Drive Info Tests."));
   1.553 +	
   1.554 +	User::LeaveIfError (TheFs.Connect ());
   1.555 +	
   1.556 +	CTrapCleanup* cleanup = CTrapCleanup::New();
   1.557 +	CActiveScheduler* scheduler = new(ELeave)CActiveScheduler;
   1.558 +	CActiveScheduler::Install(scheduler);
   1.559 +
   1.560 +	TRAPD(err,DoTestsL());
   1.561 +	TESTL(err==KErrNone);
   1.562 +	
   1.563 +	delete scheduler;
   1.564 +	delete cleanup;
   1.565 +	
   1.566 +	TheFs.Close();
   1.567 +	
   1.568 +	TheTest.End();
   1.569 +	TheTest.Close();
   1.570 +	
   1.571 +	__UHEAP_MARKEND;
   1.572 +	return(0);
   1.573 +	}