os/ossrv/lowlevellibsandfws/pluginfw/Framework/DriveInfoTest/t_driveinfo.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// This file contains code to test the EcomCachedDriveInfo class.
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include <e32test.h>
sl@0
    19
#include <f32file.h>
sl@0
    20
#include <ecom/ecomerrorcodes.h>
sl@0
    21
#include "EComPatchDataConstantv2.h"
sl@0
    22
#include "DriveInfo.h"
sl@0
    23
#include "EComInternalErrorCodes.h"
sl@0
    24
#define UNUSED_VAR(a) (a = a)
sl@0
    25
sl@0
    26
LOCAL_D RTest TheTest(_L("t_driveinfo"));
sl@0
    27
LOCAL_D RFs	TheFs;
sl@0
    28
static TInt IteratorPanicTest(TAny* aFuncCode);
sl@0
    29
sl@0
    30
const TInt KPanicIndexOutOfBound = 133;
sl@0
    31
_LIT(KTestFolder,			"C:\\TestTemp\\");
sl@0
    32
sl@0
    33
enum TIteratorFunctionToTest
sl@0
    34
	{
sl@0
    35
	EIterFunctionDriveUnit,
sl@0
    36
	EIterFunctionDriveNumber,
sl@0
    37
	EIterFunctionIsReadOnlyInternal,
sl@0
    38
	EIterFunctionIsRemovable
sl@0
    39
	};
sl@0
    40
sl@0
    41
class TDriveInfo_StateAccessor 
sl@0
    42
	{
sl@0
    43
public:
sl@0
    44
	static CEComCachedDriveInfo* GetCachedDriveInfoL(RFs& aFs, TUint32 aDrvMask);
sl@0
    45
	static void EComDrvFlagsL(TInt aDriveNum,
sl@0
    46
							  TUint32& aDrvFlags,
sl@0
    47
							  const CEComCachedDriveInfo& aCachedDriveInfo);
sl@0
    48
	};
sl@0
    49
sl@0
    50
/**
sl@0
    51
Because this class is friend of CEComCachedDriveInfo, it can call the
sl@0
    52
private constructor of CEComCachedDriveInfo to make object instance
sl@0
    53
with drive disabled mask different from the patchable constant.
sl@0
    54
@param aFs Connected RFs session.
sl@0
    55
@param aDrvMask The discovery disabled drive mask to pass to
sl@0
    56
	CEComCachedDriveInfo.
sl@0
    57
@return fully constructed CEComCachedDriveInfo. Caller owns the pointer.
sl@0
    58
@leave KErrNoMemory if system out of memory.
sl@0
    59
*/
sl@0
    60
CEComCachedDriveInfo* TDriveInfo_StateAccessor::GetCachedDriveInfoL(
sl@0
    61
	RFs&	aFs,
sl@0
    62
	TUint32 aDrvMask)
sl@0
    63
	{
sl@0
    64
	// Set this bool to false otherwise ConstructL will do nothing.
sl@0
    65
	CEComCachedDriveInfo::iInitialized = EFalse;
sl@0
    66
sl@0
    67
	CEComCachedDriveInfo* ptr = new (ELeave) CEComCachedDriveInfo();
sl@0
    68
	CleanupStack::PushL(ptr);
sl@0
    69
	ptr->ConstructL(aFs, aDrvMask);
sl@0
    70
	CleanupStack::Pop();
sl@0
    71
	return ptr;
sl@0
    72
	}
sl@0
    73
sl@0
    74
/**
sl@0
    75
static method
sl@0
    76
sl@0
    77
Retrieve the flag word stored by CEComCachedDriveInfo about a given drive.
sl@0
    78
@param aDriveNum the drive of interest
sl@0
    79
@param aDrvFlags output parameter to return the drive attributes
sl@0
    80
@param aCachedDriveInfo the object instance to access.
sl@0
    81
@leave KErrNotFound if no such drive
sl@0
    82
*/
sl@0
    83
void TDriveInfo_StateAccessor::EComDrvFlagsL(TInt aDriveNum,
sl@0
    84
											TUint32& aDrvFlags,
sl@0
    85
											const CEComCachedDriveInfo& aCachedDriveInfo)
sl@0
    86
	{
sl@0
    87
	for (TInt i = 0; i <= aCachedDriveInfo.iLastIndex; i++)
sl@0
    88
		{
sl@0
    89
		if (aCachedDriveInfo.iDriveAttr[i].iDrvNumber == aDriveNum)
sl@0
    90
			{
sl@0
    91
			aDrvFlags = aCachedDriveInfo.iDriveAttr[i].iFlags;
sl@0
    92
			return;
sl@0
    93
			}
sl@0
    94
		}
sl@0
    95
sl@0
    96
	User::Leave(KErrNotFound);
sl@0
    97
	}
sl@0
    98
sl@0
    99
//Test macroses and functions
sl@0
   100
LOCAL_C void CheckL(TInt aValue, TInt aLine)
sl@0
   101
	{
sl@0
   102
	if(!aValue)
sl@0
   103
		{
sl@0
   104
		TheTest(EFalse, aLine);
sl@0
   105
		}
sl@0
   106
	}
sl@0
   107
#define TESTL(arg) ::CheckL((arg), __LINE__)
sl@0
   108
sl@0
   109
sl@0
   110
/** Check CEComCachedDriveInfo has the correct attributes for the given drive
sl@0
   111
and the iterator will return the drive if discovery is not disabled.
sl@0
   112
*/
sl@0
   113
LOCAL_C void VerifyDrvAttributeL(const TInt aDriveNum, 
sl@0
   114
						  		TUint32 aDisableMask,
sl@0
   115
							  	const CEComCachedDriveInfo& aCachedDriveInfo)
sl@0
   116
	{
sl@0
   117
	TEComCachedDriveInfoIterator iter(aCachedDriveInfo);
sl@0
   118
sl@0
   119
	TDriveInfo driveInfo;
sl@0
   120
	User::LeaveIfError(TheFs.Drive(driveInfo, aDriveNum));
sl@0
   121
sl@0
   122
	if (0 == driveInfo.iDriveAtt)
sl@0
   123
		{
sl@0
   124
		// Drive not exist, i.e. drive letter not in-used
sl@0
   125
sl@0
   126
		TESTL( !iter.SetPos(aDriveNum) );
sl@0
   127
		return;
sl@0
   128
		}
sl@0
   129
sl@0
   130
	TUint32 expectedAttr = 0;
sl@0
   131
	if ((driveInfo.iDriveAtt & KDriveAttInternal) &&
sl@0
   132
		(driveInfo.iMediaAtt & KMediaAttWriteProtected))
sl@0
   133
		{
sl@0
   134
		// Drive is ROnly internal which cannot be disabled.
sl@0
   135
		expectedAttr = EEComDrvAttrReadOnlyInternal;
sl@0
   136
		}
sl@0
   137
	else
sl@0
   138
		{
sl@0
   139
		TUint32 drvBitMask = 1;
sl@0
   140
		if ((drvBitMask << aDriveNum) & aDisableMask ||
sl@0
   141
			driveInfo.iDriveAtt & KDriveAttSubsted ||
sl@0
   142
			driveInfo.iDriveAtt & KDriveAttRemote)
sl@0
   143
			{
sl@0
   144
			expectedAttr |= EEComDrvAttrNoDiscovery;
sl@0
   145
			}
sl@0
   146
		
sl@0
   147
		if (driveInfo.iDriveAtt & KDriveAttRemovable)
sl@0
   148
			{
sl@0
   149
			expectedAttr |= EEComDrvAttrRemovable;
sl@0
   150
			}
sl@0
   151
		
sl@0
   152
		if (0 == (driveInfo.iDriveAtt & KDriveAttRom))
sl@0
   153
			{
sl@0
   154
			expectedAttr |= EEComDrvAttrWritable;
sl@0
   155
			}
sl@0
   156
		}
sl@0
   157
sl@0
   158
	// Test iterator does not return disabled drives.
sl@0
   159
	TBool found = EFalse;
sl@0
   160
	for (iter.First(); iter.InRange() && !found; iter.Next())
sl@0
   161
		{
sl@0
   162
		if (iter.DriveNumber() == aDriveNum)
sl@0
   163
			{
sl@0
   164
			found = ETrue;
sl@0
   165
			}
sl@0
   166
		}
sl@0
   167
sl@0
   168
	TBool expectedFound = !(expectedAttr & EEComDrvAttrNoDiscovery);
sl@0
   169
	if (found != expectedFound)
sl@0
   170
		{
sl@0
   171
		TheTest.Printf(_L("Error drive %d, expected att 0x%X, iter found %d"), aDriveNum, expectedAttr, found);
sl@0
   172
		}
sl@0
   173
	TESTL(expectedFound == found);
sl@0
   174
sl@0
   175
	// verify drive attributes
sl@0
   176
	TUint32 actualAttr = 0;
sl@0
   177
	TDriveInfo_StateAccessor::EComDrvFlagsL(aDriveNum, actualAttr,
sl@0
   178
		aCachedDriveInfo);
sl@0
   179
	if (actualAttr != expectedAttr)
sl@0
   180
		{
sl@0
   181
		TheTest.Printf(_L("Error drive %d, expected att 0x%X, got 0x%X"), aDriveNum, expectedAttr, actualAttr);
sl@0
   182
		}
sl@0
   183
	TESTL(actualAttr == expectedAttr);
sl@0
   184
	}
sl@0
   185
sl@0
   186
/**
sl@0
   187
@SYMTestCaseID			SYSLIB-ECOM-UT-3536
sl@0
   188
@SYMTestCaseDesc		Disable/enable each drive and verify CEComCachedDriveInfo
sl@0
   189
	has correct attribute for each drive and the iterator will not return
sl@0
   190
	drives that are disabled, subst or remote.
sl@0
   191
@SYMTestPriority		High
sl@0
   192
@SYMTestActions			Instantiate CEComCachedDriveInfo with each drive
sl@0
   193
	disabled in turn. Verify the attribute and iterator operation on the drive.
sl@0
   194
	Instantiate CEComCachedDriveInfo with all drive enable. Verify
sl@0
   195
	attribute and iterator operation on each drive.
sl@0
   196
@SYMTestExpectedResults	CEComCachedDriveInfo has the expected attributes for
sl@0
   197
	each drive whethe the drive is enabled or disabled. The iterator will only
sl@0
   198
	return the drive is the drive is enabled.
sl@0
   199
@SYMCR					CR1049
sl@0
   200
*/
sl@0
   201
LOCAL_C void DriveMaskTestL()
sl@0
   202
	{
sl@0
   203
	CEComCachedDriveInfo* cachedDriveInfo;
sl@0
   204
sl@0
   205
	// Disable each drive in turn to check that disable works as expected.
sl@0
   206
	TInt i;
sl@0
   207
	for (i = EDriveA; i <= EDriveZ; i++)
sl@0
   208
		{
sl@0
   209
		TUint32 disableMask = 1 << i;
sl@0
   210
		cachedDriveInfo = TDriveInfo_StateAccessor::GetCachedDriveInfoL(TheFs, disableMask);
sl@0
   211
		CleanupStack::PushL(cachedDriveInfo);
sl@0
   212
sl@0
   213
		// Check CEComCachedDriveInfo has the expected value.
sl@0
   214
		VerifyDrvAttributeL(i, disableMask, *cachedDriveInfo);
sl@0
   215
sl@0
   216
		// Test CEComCachedDriveInfo::DriveIsReadOnlyInternalL and 
sl@0
   217
		// DriveIsRemovableL leaving. They should be used on drives that
sl@0
   218
		// are known to be valid, e.g. drive extracted from the path
sl@0
   219
		// of a discovered DLL.
sl@0
   220
		// Since C: is disabled, CEComCachedDriveInfo will leave instead
sl@0
   221
		// of answering true or false (because the answer is misleading).
sl@0
   222
		if (i == EDriveC)
sl@0
   223
			{
sl@0
   224
			TRAPD(err, cachedDriveInfo->DriveIsReadOnlyInternalL(i) );
sl@0
   225
			TESTL(err == KEComErrDriveNotFound);
sl@0
   226
sl@0
   227
			TRAP(err, cachedDriveInfo->DriveIsRemovableL(i) );
sl@0
   228
			TESTL(err == KEComErrDriveNotFound);
sl@0
   229
			}
sl@0
   230
sl@0
   231
		CleanupStack::PopAndDestroy(cachedDriveInfo);
sl@0
   232
		}
sl@0
   233
sl@0
   234
	// Test enable case.
sl@0
   235
	// Make sure the disable mask is zero.
sl@0
   236
	TESTL(KDiscoveryDisabledDriveList == 0);
sl@0
   237
sl@0
   238
	cachedDriveInfo = TDriveInfo_StateAccessor::GetCachedDriveInfoL(TheFs,0);
sl@0
   239
	CleanupStack::PushL(cachedDriveInfo);
sl@0
   240
sl@0
   241
	for (i = EDriveA; i < KMaxDrives; i++)
sl@0
   242
		{
sl@0
   243
		VerifyDrvAttributeL(i, 0, *cachedDriveInfo);
sl@0
   244
		}
sl@0
   245
sl@0
   246
	CleanupStack::PopAndDestroy(cachedDriveInfo);
sl@0
   247
	}
sl@0
   248
sl@0
   249
/**
sl@0
   250
@SYMTestCaseID			SYSLIB-ECOM-UT-3537
sl@0
   251
@SYMTestCaseDesc		Test the CEComCachedDriveInfo and its iterator classes
sl@0
   252
	handles substituted drives correctly.
sl@0
   253
@SYMTestPriority		High
sl@0
   254
@SYMTestActions			Create a substituted drive, instantiate the cached drive info and verify that 
sl@0
   255
						the sustitued drive is not in the valid drive list.
sl@0
   256
@SYMTestExpectedResults	Substituted drive is not in the valid drive list.
sl@0
   257
@SYMCR					CR1049
sl@0
   258
*/
sl@0
   259
LOCAL_C void SubstitutedDriveTestL()
sl@0
   260
	{
sl@0
   261
	//Create c:\TestTemp folder
sl@0
   262
	TInt err = TheFs.MkDir(KTestFolder);
sl@0
   263
	//Create substituted drive L:, it maps to C:\TestTemp\ folder
sl@0
   264
	err = TheFs.SetSubst(KTestFolder,EDriveL);
sl@0
   265
	TESTL(err==KErrNone);
sl@0
   266
sl@0
   267
	//Verify that L Drive is not in the valid list.	
sl@0
   268
	CEComCachedDriveInfo* cachedDriveInfo =
sl@0
   269
		TDriveInfo_StateAccessor::GetCachedDriveInfoL(TheFs,0);
sl@0
   270
	CleanupStack::PushL(cachedDriveInfo);
sl@0
   271
sl@0
   272
	VerifyDrvAttributeL(EDriveL, 0, *cachedDriveInfo);
sl@0
   273
sl@0
   274
	CleanupStack::PopAndDestroy(cachedDriveInfo);
sl@0
   275
sl@0
   276
	// undo subst
sl@0
   277
	err = TheFs.SetSubst(KNullDesC, EDriveL);
sl@0
   278
	TESTL(err==KErrNone);
sl@0
   279
sl@0
   280
	err = TheFs.RmDir(KTestFolder);
sl@0
   281
	TESTL(err==KErrNone);
sl@0
   282
	}
sl@0
   283
sl@0
   284
/**
sl@0
   285
@SYMTestCaseID			SYSLIB-ECOM-UT-3539
sl@0
   286
@SYMTestCaseDesc		Test the various methods exposed by TEComCachedDriveInfoIterator class.
sl@0
   287
@SYMTestPriority		High
sl@0
   288
@SYMTestActions			For each drive returned by the iterator, call all the
sl@0
   289
	getter methods.
sl@0
   290
@SYMTestExpectedResults	No leave or panic occur.
sl@0
   291
@SYMCR					CR1049
sl@0
   292
*/
sl@0
   293
LOCAL_C void ExerciseIterator()
sl@0
   294
	{
sl@0
   295
	CEComCachedDriveInfo* cachedDriveInfo = CEComCachedDriveInfo::NewL(TheFs);
sl@0
   296
	CleanupStack::PushL(cachedDriveInfo);
sl@0
   297
sl@0
   298
	TEComCachedDriveInfoIterator iter(*cachedDriveInfo);
sl@0
   299
sl@0
   300
	for (iter.Last(); iter.InRange(); iter.Prev())
sl@0
   301
		{
sl@0
   302
		TDriveNumber drvNum = iter.DriveNumber();
sl@0
   303
		TDriveUnit drvUnit = iter.DriveUnit();
sl@0
   304
sl@0
   305
		// A trivial test just to use the returned objects.
sl@0
   306
		TESTL(drvNum == drvUnit);
sl@0
   307
sl@0
   308
		TBool b = iter.DriveIsReadOnlyInternal();
sl@0
   309
		UNUSED_VAR(b);
sl@0
   310
sl@0
   311
		b = iter.DriveIsRemovable();
sl@0
   312
		UNUSED_VAR(b);
sl@0
   313
		}
sl@0
   314
sl@0
   315
	CleanupStack::PopAndDestroy(cachedDriveInfo);
sl@0
   316
	}
sl@0
   317
sl@0
   318
/**
sl@0
   319
Intended Usage	: Capture the PANIC that occurs in the thread.
sl@0
   320
@param			: aName The name to be assigned to this thread. 
sl@0
   321
@param			: aFunction The function which causes the panic.
sl@0
   322
*/
sl@0
   323
LOCAL_C void ThreadPanicTest(const TDesC& aName,TThreadFunction aFunction)
sl@0
   324
	{
sl@0
   325
	TheTest.Next(aName);
sl@0
   326
	TRequestStatus threadStatus;
sl@0
   327
	RThread thread;
sl@0
   328
	TBool jit;
sl@0
   329
	jit=User::JustInTime();
sl@0
   330
	User::SetJustInTime(EFalse);
sl@0
   331
sl@0
   332
	for (TInt i = EIterFunctionDriveUnit; i <= EIterFunctionIsRemovable; i++)
sl@0
   333
		{
sl@0
   334
		TIteratorFunctionToTest func = static_cast<TIteratorFunctionToTest>(i);
sl@0
   335
		TInt err=thread.Create(aName,aFunction,KDefaultStackSize,KMinHeapSize,KMinHeapSize, &func);
sl@0
   336
		TESTL(err==KErrNone);
sl@0
   337
	
sl@0
   338
		thread.Logon(threadStatus);
sl@0
   339
		thread.Resume();
sl@0
   340
		User::WaitForRequest(threadStatus);
sl@0
   341
sl@0
   342
		//Now check why the thread Exit
sl@0
   343
		TExitType exitType = thread.ExitType();
sl@0
   344
		TInt exitReason = thread.ExitReason();
sl@0
   345
		TheTest.Printf(_L("PanicTest: exitType %d, reason %d\n"), exitType, exitReason);
sl@0
   346
sl@0
   347
		TESTL(exitType == EExitPanic);
sl@0
   348
		TESTL(exitReason == KPanicIndexOutOfBound);
sl@0
   349
		thread.Close();
sl@0
   350
		}
sl@0
   351
sl@0
   352
	User::SetJustInTime(jit);
sl@0
   353
	}
sl@0
   354
sl@0
   355
/**
sl@0
   356
@SYMTestCaseID			SYSLIB-ECOM-UT-3540
sl@0
   357
@SYMTestCaseDesc		Test the TEComCachedDriveInfoIterator class will panic if object instance of this class access out of bound elements.
sl@0
   358
@SYMTestPriority		High
sl@0
   359
@SYMTestActions			Cause the iterator to panic by accessing out of range
sl@0
   360
	cell.
sl@0
   361
@SYMTestExpectedResults	Panic occur.
sl@0
   362
@SYMCR					CR1049
sl@0
   363
*/
sl@0
   364
LOCAL_C void DoIteratorPanicTestL(TIteratorFunctionToTest aFuncCode)
sl@0
   365
	{
sl@0
   366
	CEComCachedDriveInfo* cachedDriveInfo = CEComCachedDriveInfo::NewL(TheFs);
sl@0
   367
	CleanupStack::PushL(cachedDriveInfo);
sl@0
   368
sl@0
   369
	TEComCachedDriveInfoIterator iter(*cachedDriveInfo);
sl@0
   370
	// Run the iterator out of range.
sl@0
   371
	for (iter.Last(); iter.InRange(); iter.Prev())
sl@0
   372
		{
sl@0
   373
		}
sl@0
   374
sl@0
   375
	// Access the getter function to trigger panic.
sl@0
   376
	switch (aFuncCode)
sl@0
   377
		{
sl@0
   378
		case EIterFunctionDriveUnit:
sl@0
   379
			{
sl@0
   380
			TDriveUnit d = iter.DriveUnit();
sl@0
   381
			break;
sl@0
   382
			}
sl@0
   383
		case EIterFunctionDriveNumber:
sl@0
   384
			{
sl@0
   385
			TDriveNumber d = iter.DriveNumber();
sl@0
   386
			break;
sl@0
   387
			}
sl@0
   388
		case EIterFunctionIsReadOnlyInternal:
sl@0
   389
			{
sl@0
   390
			TBool f = iter.DriveIsReadOnlyInternal();
sl@0
   391
			break;
sl@0
   392
			}
sl@0
   393
		case EIterFunctionIsRemovable:
sl@0
   394
			{
sl@0
   395
			TBool f = iter.DriveIsRemovable();
sl@0
   396
			break;
sl@0
   397
			}
sl@0
   398
		default:
sl@0
   399
			// do nothing and the test will fail.
sl@0
   400
			break;
sl@0
   401
		}
sl@0
   402
sl@0
   403
	CleanupStack::PopAndDestroy(cachedDriveInfo);
sl@0
   404
	}
sl@0
   405
sl@0
   406
/**
sl@0
   407
@SYMTestCaseID			SYSLIB-ECOM-CT-1485
sl@0
   408
@SYMTestCaseDesc		Tests EcomCachedDriveInfo class.
sl@0
   409
@SYMTestPriority			High
sl@0
   410
@SYMTestActions			Test the various methods exposed by EcomCachedDriveInfo,
sl@0
   411
						 ensuring that the returned values are correct.
sl@0
   412
@SYMTestExpectedResults	The test must not fail.
sl@0
   413
@SYMDEF				 DEF073919
sl@0
   414
*/
sl@0
   415
LOCAL_C void SystemDriveTestL()
sl@0
   416
	{
sl@0
   417
	CEComCachedDriveInfo* cachedDriveInfo = CEComCachedDriveInfo::NewL(TheFs);
sl@0
   418
	CleanupStack::PushL(cachedDriveInfo);
sl@0
   419
sl@0
   420
	TDriveNumber driveSys = RFs::GetSystemDrive();
sl@0
   421
	TESTL( !cachedDriveInfo->DriveIsReadOnlyInternalL(driveSys) );
sl@0
   422
	TESTL(  cachedDriveInfo->DriveIsWritableL(driveSys) );
sl@0
   423
sl@0
   424
	// The old EcomCachedDriveInfo class has DriveIsRemoteL and
sl@0
   425
	// DriveIsSubstL methods. To verify that system drive is neither
sl@0
   426
	// remote nor subst, use TEComCachedDriveInfoIterator::SetPos().
sl@0
   427
	
sl@0
   428
	TEComCachedDriveInfoIterator iter(*cachedDriveInfo);
sl@0
   429
	TESTL( iter.SetPos(driveSys) );
sl@0
   430
sl@0
   431
	// Test Z: drive property
sl@0
   432
	TESTL( cachedDriveInfo->DriveIsReadOnlyInternalL(EDriveZ) );
sl@0
   433
	
sl@0
   434
	CleanupStack::PopAndDestroy(cachedDriveInfo);
sl@0
   435
	}
sl@0
   436
sl@0
   437
/** Setup the TRAP harness to invoke DoIteratorPanicTestL
sl@0
   438
*/
sl@0
   439
TInt IteratorPanicTest(TAny* aFuncCode)
sl@0
   440
	{
sl@0
   441
	CTrapCleanup* threadcleanup = CTrapCleanup::New();
sl@0
   442
	TIteratorFunctionToTest* funcCode = static_cast<TIteratorFunctionToTest*>(aFuncCode);
sl@0
   443
	TRAPD(ret, DoIteratorPanicTestL(*funcCode)); 
sl@0
   444
sl@0
   445
	delete threadcleanup;
sl@0
   446
	return ret;
sl@0
   447
	}
sl@0
   448
sl@0
   449
typedef void (*ClassFuncPtrL) (void);
sl@0
   450
/**
sl@0
   451
Test under OOM conditions.
sl@0
   452
This is a wrapper function to call all test functions.
sl@0
   453
@param	aTestFunctionL	 Pointer to test function.
sl@0
   454
@param		aTestDesc test function name
sl@0
   455
*/
sl@0
   456
LOCAL_C void DoOOMTestL(ClassFuncPtrL aTestFunctionL, const TDesC& aTestDesc)
sl@0
   457
	{
sl@0
   458
	TheTest.Next(aTestDesc);
sl@0
   459
	TInt err = KErrNone;
sl@0
   460
	TInt tryCount = 0;
sl@0
   461
	do
sl@0
   462
		{
sl@0
   463
		__UHEAP_MARK;
sl@0
   464
sl@0
   465
		// find out the number of open handles
sl@0
   466
		TInt startProcessHandleCount;
sl@0
   467
		TInt startThreadHandleCount;
sl@0
   468
		RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);
sl@0
   469
sl@0
   470
		__UHEAP_SETFAIL(RHeap::EDeterministic, ++tryCount);
sl@0
   471
	
sl@0
   472
		TRAP(err, aTestFunctionL());
sl@0
   473
sl@0
   474
		__UHEAP_SETFAIL(RHeap::ENone, 0);
sl@0
   475
		
sl@0
   476
		// check that no handles have leaked
sl@0
   477
		TInt endProcessHandleCount;
sl@0
   478
		TInt endThreadHandleCount; 
sl@0
   479
		RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);
sl@0
   480
		TESTL(startProcessHandleCount == endProcessHandleCount);
sl@0
   481
		TESTL(startThreadHandleCount  == endThreadHandleCount);
sl@0
   482
sl@0
   483
		__UHEAP_MARKEND;
sl@0
   484
		} while(err == KErrNoMemory);
sl@0
   485
sl@0
   486
 	TESTL(err==KErrNone);
sl@0
   487
	TheTest.Printf(_L("- succeeded at heap failure rate of %i\n"), tryCount);
sl@0
   488
	}
sl@0
   489
sl@0
   490
/**
sl@0
   491
Wrapper function to call all test functions
sl@0
   492
@param		aTestFunctionL pointer to test function
sl@0
   493
@param		aTestDesc test function name
sl@0
   494
*/
sl@0
   495
LOCAL_C void DoBasicTestL(ClassFuncPtrL aTestFunctionL, const TDesC& aTestDesc)
sl@0
   496
	{
sl@0
   497
	TheTest.Next(aTestDesc);
sl@0
   498
	__UHEAP_MARK;
sl@0
   499
  	// find out the number of open handles
sl@0
   500
	TInt startProcessHandleCount;
sl@0
   501
	TInt startThreadHandleCount;
sl@0
   502
	RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);
sl@0
   503
sl@0
   504
	aTestFunctionL();
sl@0
   505
	
sl@0
   506
	// check that no handles have leaked
sl@0
   507
	TInt endProcessHandleCount;
sl@0
   508
	TInt endThreadHandleCount;
sl@0
   509
	RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);
sl@0
   510
sl@0
   511
	TESTL(startProcessHandleCount == endProcessHandleCount);
sl@0
   512
	TESTL(startThreadHandleCount  == endThreadHandleCount);
sl@0
   513
sl@0
   514
	__UHEAP_MARKEND;
sl@0
   515
	}
sl@0
   516
	
sl@0
   517
LOCAL_C void DoTestsL()
sl@0
   518
	{
sl@0
   519
	__UHEAP_MARK;
sl@0
   520
sl@0
   521
	User::LeaveIfError(TheFs.Connect());
sl@0
   522
	CleanupClosePushL(TheFs);
sl@0
   523
sl@0
   524
	// normal tests
sl@0
   525
	DoBasicTestL(&DriveMaskTestL, _L("Drive Mask Test."));
sl@0
   526
	DoBasicTestL(&SubstitutedDriveTestL, _L("Substituted Drive Test."));
sl@0
   527
	DoBasicTestL(&ExerciseIterator, _L("Getter Test."));
sl@0
   528
	DoBasicTestL(&SystemDriveTestL, _L("System Drive Test."));
sl@0
   529
sl@0
   530
	// panic tests
sl@0
   531
	ThreadPanicTest(_L("Iterator Panic Testing"),IteratorPanicTest);
sl@0
   532
	
sl@0
   533
	// OOM tests
sl@0
   534
	DoOOMTestL(&DriveMaskTestL, _L("OOM Test for Drive Mask Test."));
sl@0
   535
	DoOOMTestL(&ExerciseIterator, _L("OOM Test for Getter."));
sl@0
   536
	DoOOMTestL(&SystemDriveTestL, _L("OOM Test for System Drive Test."));
sl@0
   537
	
sl@0
   538
	CleanupStack::PopAndDestroy();
sl@0
   539
	
sl@0
   540
	__UHEAP_MARKEND;
sl@0
   541
	}
sl@0
   542
sl@0
   543
sl@0
   544
GLDEF_C TInt E32Main()
sl@0
   545
	{
sl@0
   546
	__UHEAP_MARK;
sl@0
   547
		
sl@0
   548
	TheTest.Title();
sl@0
   549
	TheTest.Start(_L("Start Drive Info Tests."));
sl@0
   550
	
sl@0
   551
	User::LeaveIfError (TheFs.Connect ());
sl@0
   552
	
sl@0
   553
	CTrapCleanup* cleanup = CTrapCleanup::New();
sl@0
   554
	CActiveScheduler* scheduler = new(ELeave)CActiveScheduler;
sl@0
   555
	CActiveScheduler::Install(scheduler);
sl@0
   556
sl@0
   557
	TRAPD(err,DoTestsL());
sl@0
   558
	TESTL(err==KErrNone);
sl@0
   559
	
sl@0
   560
	delete scheduler;
sl@0
   561
	delete cleanup;
sl@0
   562
	
sl@0
   563
	TheFs.Close();
sl@0
   564
	
sl@0
   565
	TheTest.End();
sl@0
   566
	TheTest.Close();
sl@0
   567
	
sl@0
   568
	__UHEAP_MARKEND;
sl@0
   569
	return(0);
sl@0
   570
	}