kerneltest/f32test/server/t_dspace.cpp
changeset 0 a41df078684a
child 6 0173bcd7697c
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1998-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 the License "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 // f32test\server\t_dspace.cpp
       
    15 //
       
    16 //
       
    17 
       
    18 #include <f32file.h>
       
    19 #include <e32test.h>
       
    20 #include "t_server.h"
       
    21 #include "t_chlffs.h"
       
    22 
       
    23 
       
    24 /* This tests disk space notification. Using RFs::NotifyDiskSpace a client can request
       
    25 to be notified if the free disk space crosses a specified threshold. This test requires
       
    26 a card to be present in d: */
       
    27 
       
    28 GLDEF_D RTest test(_L("T_DSPACE"));
       
    29 
       
    30 const TInt KMaxBufSize=512;
       
    31 #if defined(__WINS__)
       
    32 TInt KFileSize1=2048;
       
    33 TInt KFileSize2=4096;
       
    34 TInt KFileSize3=8192;
       
    35 #else
       
    36 TInt KFileSize1=512;
       
    37 TInt KFileSize2=1024;
       
    38 TInt KFileSize3=4096;
       
    39 #endif
       
    40 
       
    41 const TInt KHeapSize=0x2000;
       
    42 const TInt KStackSize=0x4000;
       
    43 
       
    44 TInt gMinFileSize;
       
    45 
       
    46 TBool LffsDrive = EFalse;
       
    47 
       
    48 TBuf8<KMaxBufSize> TheBuffer;
       
    49 TInt64 TheDiskSize;
       
    50 TInt RemovableDrive;
       
    51 TBuf<4> RemovableDriveBuf=_L("?:\\");
       
    52 
       
    53 _LIT(KTestFile1, "\\F32-TST\\testfile1");
       
    54 _LIT(KTestFile2, "\\F32-TST\\testFile2");
       
    55 _LIT(KTestDir1, "\\F32-TST\\testDir1\\");
       
    56 _LIT(KTestDir2, "\\F32-TST\\testDir2\\");
       
    57 _LIT(KFileFiller, "\\F32-TST\\fileFiller");
       
    58 
       
    59 // functions that may cause change in free disk space
       
    60 // not all of them of tested since some require knowledge of file system
       
    61 // to ensure change in free disk space
       
    62 enum TThreadTask
       
    63 	{
       
    64 	ETaskSetVolume,
       
    65 	ETaskMkDir,
       
    66 	ETaskRmDir,
       
    67 	ETaskDelete,		// test
       
    68 	ETaskRename,
       
    69 	ETaskReplace,		// test
       
    70 	ETaskFileCreate,
       
    71 	ETaskFileReplace,	// test
       
    72 	ETaskFileTemp,
       
    73 	ETaskFileWrite,		// test
       
    74 	ETaskFileWrite4KB,
       
    75 	ETaskFileWrite64KB,
       
    76 	ETaskFileSetSize,	// test
       
    77 	ETaskFileRename,
       
    78 	ETaskNoChange1,
       
    79 	ETaskNoChange2,
       
    80 	ETaskFileCreateLffs,// test
       
    81 	ETaskSpin
       
    82 	};
       
    83 
       
    84 
       
    85 LOCAL_C TBool IsWinsCDrive(TInt aDrive)
       
    86 //
       
    87 //
       
    88 //
       
    89 	{
       
    90 #if defined(__WINS__)
       
    91 	if(aDrive==KDefaultDrive)
       
    92 		return(gSessionPath[0]==(TText)'C');
       
    93 	else
       
    94 		return(aDrive==EDriveC);
       
    95 #else
       
    96 	return(EFalse);
       
    97 #endif
       
    98 	}
       
    99 
       
   100 LOCAL_C TInt64 FreeDiskSpace(TInt aDrive)
       
   101 //
       
   102 //
       
   103 //
       
   104 	{
       
   105 	TVolumeInfo v;
       
   106 	TInt r=TheFs.Volume(v,aDrive);
       
   107 	test(r==KErrNone);
       
   108 	return(v.iFree);
       
   109 	}
       
   110 
       
   111 LOCAL_C TInt64 DiskSize(TInt aDrive)
       
   112 //
       
   113 //
       
   114 //
       
   115 	{
       
   116 	TVolumeInfo v;
       
   117 	TInt r=TheFs.Volume(v,aDrive);
       
   118 	test(r==KErrNone);
       
   119 	return(v.iSize);
       
   120 	}
       
   121 
       
   122 // MinimumFileSize() -
       
   123 // Deduces the minimum space occupied by a file by creating a file of one byte
       
   124 // in length. This should equal the cluster size on FAT volumes.
       
   125 //
       
   126 LOCAL_C TInt MinimumFileSize(TInt aDrive)
       
   127 	{
       
   128 	TInt r = TheFs.Delete(KTestFile1);
       
   129 	test(r==KErrNone || r==KErrNotFound);
       
   130 
       
   131 	TInt64 freeSpace = FreeDiskSpace(aDrive);
       
   132 
       
   133 	RFile file;
       
   134 
       
   135 
       
   136 	r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
       
   137 	test(r==KErrNone);
       
   138 
       
   139 	r = file.Write(TheBuffer,1);
       
   140 	test(r==KErrNone);
       
   141 	file.Close();
       
   142 	TInt64 newSpace = FreeDiskSpace(aDrive);
       
   143 
       
   144 	r = TheFs.Delete(KTestFile1);
       
   145 	test(r==KErrNone);
       
   146 
       
   147 
       
   148 	TInt64 minFileSize = freeSpace - newSpace;
       
   149 	test (minFileSize >= 0);
       
   150 	minFileSize = Max(minFileSize, 512);
       
   151 	test (minFileSize < KMaxTInt);
       
   152 
       
   153 	TInt minFileSizeLow = I64LOW(minFileSize);
       
   154 
       
   155 	RDebug::Print(_L("minFileSize %u"), minFileSizeLow);
       
   156 
       
   157 #if defined(__WINS__)
       
   158 	KFileSize1 = minFileSizeLow << 2;	// 512 * 2^2 = 512 * 4 = 2048;
       
   159 	KFileSize2 = minFileSizeLow << 3;	// 512 * 2^3 = 512 * 8 = 4096;
       
   160 	KFileSize3 = minFileSizeLow << 4;	// 512 * 2^4 = 512 * 16 = 8192;
       
   161 #else
       
   162 	KFileSize1 = minFileSizeLow;		// 512;
       
   163 	KFileSize2 = minFileSizeLow << 1;	// 512 * 2^1 = 512 * 2 = 1024;
       
   164 	KFileSize3 = minFileSizeLow << 3;	// 512 * 2^3 = 512 * 8 = 4096;
       
   165 #endif
       
   166 
       
   167 
       
   168 	return (TInt) minFileSizeLow;
       
   169 	}
       
   170 
       
   171 LOCAL_C void Initialise()
       
   172 //
       
   173 // do any initialisation before starting tests
       
   174 //
       
   175 	{
       
   176 	if(TheBuffer.Length()!=KMaxBufSize)
       
   177 		{
       
   178 		TheBuffer.SetLength(KMaxBufSize);
       
   179 		Mem::Fill((void*)TheBuffer.Ptr(),KMaxBufSize,0xab);
       
   180 		}
       
   181 	TheDiskSize=DiskSize(KDefaultDrive);
       
   182 #if defined(__WINS__)
       
   183 	RemovableDrive=EDriveX;
       
   184 #else
       
   185 	TDriveList drvList;
       
   186 	if(KErrNone == TheFs.DriveList(drvList))
       
   187 		{
       
   188 		TInt i;
       
   189 		//should be successful, otherwise it means a system w/o any drive!!!
       
   190 		for(i=0;i<KMaxDrives;i++)
       
   191 			{
       
   192 			TDriveInfo driveInfo;
       
   193 			if((drvList[i] != 0)
       
   194 				&& (KErrNone == TheFs.Drive(driveInfo, i))
       
   195 				&& (driveInfo.iType == EMediaHardDisk))
       
   196 				{
       
   197 				RemovableDrive = i;
       
   198 				test.Printf(_L("RemovableDrive = %d\n"),RemovableDrive);
       
   199 				break;
       
   200 				}
       
   201 			}
       
   202 		if(i == KMaxDrives)
       
   203 			{
       
   204 			test.Printf(_L("No Removable media found! Testing discontinued.\n"));
       
   205 			User::Exit(KErrNone);
       
   206 			}
       
   207 		}
       
   208 	else
       
   209 		{
       
   210 		test.Printf(_L("No Drive found! Testing discontinued.\n"));
       
   211 		User::Exit(KErrNone);
       
   212 		}
       
   213 #endif
       
   214 
       
   215 	test.Printf(_L("inside init++++++++++++++++++++++++++>\n\n\n"));
       
   216 	test.Printf(_L("RemovableDrive = %d\n"),RemovableDrive);
       
   217 	// initialise removable drive descriptor
       
   218 	TChar c;
       
   219 	TInt r=RFs::DriveToChar(RemovableDrive,c);
       
   220 	test(r==KErrNone);
       
   221 	RemovableDriveBuf[0]=(TText)c;
       
   222 
       
   223 	if( !LffsDrive )
       
   224 		{
       
   225 		// and create the default directory
       
   226 		TFileName d=gSessionPath;
       
   227 		d[0]=RemovableDriveBuf[0];
       
   228 		MakeDir(d);
       
   229 		}
       
   230 
       
   231 	// better format the default drive as long as not WINS c drive
       
   232 	TInt drive;
       
   233 	r= RFs::CharToDrive(gSessionPath[0],drive);
       
   234 	test(r==KErrNone);
       
   235 #if defined(__WINS__)
       
   236 	if(drive!=EDriveC)
       
   237 		Format(drive);
       
   238 #else
       
   239 	Format(drive);
       
   240 	// test not run on c: drive but does use it
       
   241 	Format(EDriveC);
       
   242 #endif
       
   243 	// and set the default directory
       
   244 	r=TheFs.MkDirAll(gSessionPath);
       
   245 	test(r==KErrNone || r==KErrAlreadyExists);
       
   246 
       
   247 	r=TheFs.Delete(KFileFiller);
       
   248 	test(r==KErrNone || r==KErrNotFound);
       
   249 	r=TheFs.Delete(KTestFile1);
       
   250 	test(r==KErrNone || r==KErrNotFound);
       
   251 	r=TheFs.Delete(KTestFile2);
       
   252 	test(r==KErrNone || r==KErrNotFound);
       
   253 	r=TheFs.RmDir(KTestDir1);
       
   254 	test(r==KErrNone || r==KErrNotFound);
       
   255 	r=TheFs.RmDir(KTestDir2);
       
   256 	test(r==KErrNone || r==KErrNotFound);
       
   257 
       
   258 	gMinFileSize = MinimumFileSize(drive);
       
   259 	}
       
   260 
       
   261 LOCAL_C TInt64 FillDisk(RFile& aFile,TInt64 aNewSpace,TInt aDrive)
       
   262 //
       
   263 // fill a file until free disk space equals aFreeSpace
       
   264 //
       
   265 	{
       
   266 	TInt64 space=FreeDiskSpace(aDrive);
       
   267 	test(space>aNewSpace);
       
   268 	while(space>aNewSpace)
       
   269 		{
       
   270 		TInt s=Min(KMaxBufSize, I64INT(space-aNewSpace));
       
   271 		TInt r=aFile.Write(TheBuffer,s);
       
   272 		if( !LffsDrive )
       
   273 			{
       
   274 			test(r==KErrNone);
       
   275 			}
       
   276 		else
       
   277 			{
       
   278 			//
       
   279 			// LFFS is less predictable than a normal drive because of the logging
       
   280 			// and metadata arrangement
       
   281 			//
       
   282 			test( (KErrNone==r) || (KErrDiskFull==r) );
       
   283 			if( KErrDiskFull == r )
       
   284 				{
       
   285 				// shrink the file back down again to give the requested free space
       
   286 				TInt fileSize;
       
   287 				r=aFile.Size( fileSize );
       
   288 				test( KErrNone == r );
       
   289 				test( TInt64(fileSize) > aNewSpace );
       
   290 				fileSize -= I64LOW(aNewSpace);
       
   291 				r=aFile.SetSize( fileSize );
       
   292 				test( KErrNone == r );
       
   293 
       
   294 				space=FreeDiskSpace(aDrive);
       
   295 				while( space < aNewSpace )
       
   296 					{
       
   297 					fileSize -= I64LOW(aNewSpace - space);
       
   298 					test( fileSize > 0 );
       
   299 					r=aFile.SetSize( fileSize );
       
   300 					test( KErrNone == r );
       
   301 					space=FreeDiskSpace(aDrive);
       
   302 					}
       
   303 				break;
       
   304 				}
       
   305 			}
       
   306 
       
   307 		space=FreeDiskSpace(aDrive);
       
   308 		}
       
   309 	return(space);
       
   310 	}
       
   311 
       
   312 LOCAL_C void WriteToFile(RFile& aFile,TInt aSize)
       
   313 //
       
   314 //
       
   315 //
       
   316 	{
       
   317 	while(aSize>0)
       
   318 		{
       
   319 		TInt s=Min(KMaxBufSize,aSize);
       
   320 		TInt r=aFile.Write(TheBuffer,s);
       
   321 		aSize-=s;
       
   322 
       
   323 		// Flush if write caching enabled to ensure we get disk space notifications
       
   324 		if ((gDriveCacheFlags & EFileCacheWriteOn) && (r == KErrNone))
       
   325 			r = aFile.Flush();
       
   326 
       
   327 		if( !LffsDrive )
       
   328 			{
       
   329 			test(r==KErrNone);
       
   330 			}
       
   331 		else
       
   332 			{
       
   333 			// we can't accurately predict the amount of data we can actually get
       
   334 			// on an LFFS drive, so it's posible we could exceed the available
       
   335 			// space even though we are writing less that the reported free space
       
   336 			test( (KErrNone==r) || (KErrDiskFull==r) );
       
   337 			if( KErrDiskFull == r )
       
   338 				{
       
   339 				break;	// just stop
       
   340 				}
       
   341 			}
       
   342 		}
       
   343 	}
       
   344 
       
   345 
       
   346 LOCAL_C void CleanupForThread(TInt aTask)
       
   347 //
       
   348 //
       
   349 //
       
   350 	{
       
   351 	TInt r;
       
   352 	switch(aTask)
       
   353 		{
       
   354 		case ETaskMkDir:
       
   355 			r=TheFs.RmDir(KTestDir1);
       
   356 			test(r==KErrNone);
       
   357 			break;
       
   358 		case ETaskRmDir: break;
       
   359 		case ETaskDelete: break;
       
   360 		case ETaskReplace:
       
   361 			r=TheFs.Delete(KTestFile2);
       
   362 			test(r==KErrNone);
       
   363 			break;
       
   364 		case ETaskFileReplace:
       
   365 			r=TheFs.Delete(KTestFile1);
       
   366 			test(r==KErrNone);
       
   367 			break;
       
   368 		case ETaskFileWrite:
       
   369 		case ETaskFileWrite4KB:
       
   370 		case ETaskFileWrite64KB:
       
   371 		case ETaskFileSetSize:
       
   372 		case ETaskFileCreateLffs:
       
   373 		case ETaskNoChange1:
       
   374 		case ETaskNoChange2:
       
   375 			r=TheFs.Delete(KTestFile1);
       
   376 			if(r!=KErrNone)
       
   377 				{
       
   378 				test.Printf(_L("r=%d"),r);
       
   379 				test(EFalse);
       
   380 				}
       
   381 			break;
       
   382 		case ETaskSpin:
       
   383 		default:break;
       
   384 		}
       
   385 	}
       
   386 
       
   387 LOCAL_C void InitialiseForThread(TInt aTask)
       
   388 //
       
   389 //
       
   390 //
       
   391 	{
       
   392 	TInt r;
       
   393 	RFile file,file2;
       
   394 	switch(aTask)
       
   395 		{
       
   396 		case ETaskMkDir:	break;
       
   397 		case ETaskRmDir:
       
   398 			r=TheFs.MkDir(KTestDir1);
       
   399 			test(r==KErrNone);
       
   400 			break;
       
   401 		case ETaskDelete:
       
   402 			r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
       
   403 			test(r==KErrNone);
       
   404 			if( !LffsDrive )
       
   405 				{
       
   406 				r=file.SetSize(KFileSize1);
       
   407 				test(r==KErrNone);
       
   408 				}
       
   409 			else
       
   410 				{
       
   411 				// LFFS supports sparse files, so we have to write real data
       
   412 				// into the file to ensure that it uses up disk space
       
   413 				WriteToFile( file, KFileSize1 );
       
   414 				}
       
   415 			file.Close();
       
   416 			break;
       
   417 		case ETaskReplace:
       
   418 			r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
       
   419 			test(r==KErrNone);
       
   420 			if( !LffsDrive )
       
   421 				{
       
   422 				r=file.SetSize(KFileSize1);
       
   423 				test(r==KErrNone);
       
   424 				}
       
   425 			else
       
   426 				{
       
   427 				WriteToFile( file, KFileSize2 );
       
   428 				}
       
   429 			file.Close();
       
   430 			r=file2.Create(TheFs,KTestFile2,EFileShareAny|EFileWrite);
       
   431 			test(r==KErrNone);
       
   432 			if( !LffsDrive )
       
   433 				{
       
   434 				r=file2.SetSize(KFileSize3);
       
   435 				test(r==KErrNone);
       
   436 				}
       
   437 			else
       
   438 				{
       
   439 				WriteToFile( file2, gMinFileSize << 4);	// 512 * 16 = 8K
       
   440 				}
       
   441 			file2.Close();
       
   442 			break;
       
   443 		case ETaskFileReplace:
       
   444 			r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
       
   445 			test(r==KErrNone);
       
   446 			if( !LffsDrive )
       
   447 				{
       
   448 				r=file.SetSize(KFileSize3*2);
       
   449 				}
       
   450 			else
       
   451 				{
       
   452 				WriteToFile( file, KFileSize3 );
       
   453 				}
       
   454 			test(r==KErrNone);
       
   455 			file.Close();
       
   456 			break;
       
   457 		case ETaskFileWrite:
       
   458 		case ETaskFileWrite4KB:
       
   459 		case ETaskFileWrite64KB:
       
   460 		case ETaskFileSetSize:
       
   461 			r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
       
   462 			test(r==KErrNone);
       
   463 			file.Close();
       
   464 			break;
       
   465 		case ETaskNoChange1:
       
   466 			r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
       
   467 			test(r==KErrNone);
       
   468 			if( !LffsDrive )
       
   469 				{
       
   470 				r=file.SetSize(KFileSize1);
       
   471 				test(r==KErrNone);
       
   472 				}
       
   473 			else
       
   474 				{
       
   475 				WriteToFile( file, KFileSize1 );
       
   476 				}
       
   477 			file.Close();
       
   478 			break;
       
   479 		case ETaskNoChange2:
       
   480 			r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
       
   481 			test(r==KErrNone);
       
   482 			file.Close();
       
   483 			break;
       
   484 		case ETaskFileCreateLffs:
       
   485 			r = TheFs.Delete(KTestFile1);
       
   486 			break;
       
   487 		case ETaskSpin:
       
   488 		default:break;
       
   489 		}
       
   490 	}
       
   491 
       
   492 LOCAL_C TInt ThreadFunction(TAny* aThreadTask)
       
   493 //
       
   494 //
       
   495 //
       
   496 	{
       
   497 	RTest test(_L("T_DSPACE_ThreadFunction"));
       
   498 	RFs fs;
       
   499 	TInt r=fs.Connect();
       
   500 	test(r==KErrNone);
       
   501 	r=fs.SetSessionPath(gSessionPath);
       
   502 	test(r==KErrNone);
       
   503 	TThreadTask task=*(TThreadTask*)&aThreadTask;
       
   504 	RFile file;
       
   505 	switch(task)
       
   506 		{
       
   507 		case ETaskMkDir:
       
   508 			r=fs.MkDir(KTestDir1);
       
   509 			test(r==KErrNone);
       
   510 			break;
       
   511 		case ETaskRmDir:
       
   512 			r=fs.RmDir(KTestDir1);
       
   513 			test(r==KErrNone);
       
   514 			break;
       
   515 		case ETaskDelete:
       
   516 			r=fs.Delete(KTestFile1);
       
   517 			test(r==KErrNone);
       
   518 			break;
       
   519 		case ETaskReplace:
       
   520 			r=fs.Replace(KTestFile1,KTestFile2);
       
   521 			test(r==KErrNone);
       
   522 			break;
       
   523 		case ETaskFileReplace:
       
   524 			r=file.Replace(fs,KTestFile1,EFileShareAny|EFileWrite);
       
   525 			test(r==KErrNone);
       
   526 			file.Close();
       
   527 			break;
       
   528 		case ETaskFileWrite:
       
   529 			r=file.Open(fs,KTestFile1,EFileShareAny|EFileWrite);
       
   530 			test(r==KErrNone);
       
   531 #if defined(__WINS__)
       
   532 			WriteToFile( file, gMinFileSize << 4);	// 512 * 16 = 8K
       
   533 #else
       
   534 			WriteToFile( file, gMinFileSize << 1);	// 512 * 2 = 1K
       
   535 #endif
       
   536 			file.Close();
       
   537 			break;
       
   538 		case ETaskFileWrite4KB:
       
   539 			r=file.Open(fs,KTestFile1,EFileShareAny|EFileWrite);
       
   540 			test(r==KErrNone);
       
   541 			WriteToFile(file,gMinFileSize << 3);	// 512 * 2^3 = 512 * 8 = 4K
       
   542 			file.Close();
       
   543 			break;
       
   544 		case ETaskFileWrite64KB:
       
   545 			r=file.Open(fs,KTestFile1,EFileShareAny|EFileWrite);
       
   546 			test(r==KErrNone);
       
   547 			WriteToFile(file,gMinFileSize<<7);	// 512 * 2^7 = 512 * 128 = 64K
       
   548 			file.Close();
       
   549 			break;
       
   550 		case ETaskFileSetSize:
       
   551 			r=file.Open(fs,KTestFile1,EFileShareAny|EFileWrite);
       
   552 			test(r==KErrNone);
       
   553 			r=file.SetSize(KFileSize3);
       
   554 			file.Close();
       
   555 			break;
       
   556 		case ETaskFileCreateLffs:
       
   557 			r=file.Create(fs,KTestFile1,EFileShareAny|EFileWrite);
       
   558 			test(r==KErrNone);
       
   559 			file.Close();
       
   560 			break;
       
   561 		case ETaskNoChange1:
       
   562 			{
       
   563 			r=file.Open(fs,KTestFile1,EFileShareAny|EFileWrite);
       
   564 			test(r==KErrNone);
       
   565 			TTime time;
       
   566 			time.HomeTime();
       
   567 			r=file.SetModified(time);
       
   568 			test(r==KErrNone);
       
   569 			file.Close();
       
   570 			break;
       
   571 			}
       
   572 		case ETaskNoChange2:
       
   573 			{
       
   574 			TEntry e;
       
   575 			r=fs.Entry(KTestFile1,e);
       
   576 			test(r==KErrNone);
       
   577 			break;
       
   578 			}
       
   579 		case ETaskSpin:
       
   580 			for(;;) {};
       
   581 
       
   582 		default:break;
       
   583 		}
       
   584 	fs.Close();
       
   585 	return(KErrNone);
       
   586 	}
       
   587 
       
   588 
       
   589 void TestCancellation()
       
   590 //
       
   591 // test error disk space notification requests can be cancelled
       
   592 //
       
   593 	{
       
   594 	test.Next(_L("test disk space cancellation"));
       
   595 	const TInt ThresholdSize=500;
       
   596 	// test a cancellation
       
   597 	// Up the priority of this thread so that we can cancel the request before the drive thread
       
   598 	// runs, to test whether cancelling still works.
       
   599 	RThread().SetPriority(EPriorityRealTime);
       
   600 	TRequestStatus stat1;
       
   601 	TheFs.NotifyDiskSpace(ThresholdSize,KDefaultDrive,stat1);
       
   602 	test(stat1==KRequestPending);
       
   603 	TheFs.NotifyDiskSpaceCancel(stat1);
       
   604 	test(stat1==KErrCancel);
       
   605 	RThread().SetPriority(EPriorityNormal);
       
   606 	// test no affect if already cancelled
       
   607 	stat1=KErrNone;
       
   608 	TheFs.NotifyDiskSpaceCancel(stat1);
       
   609 	test(stat1==KErrNone);
       
   610 	// set up two requests, cancel 1
       
   611 	TRequestStatus stat2;
       
   612 	TheFs.NotifyDiskSpace(ThresholdSize,KDefaultDrive,stat1);
       
   613 	TheFs.NotifyDiskSpace(ThresholdSize,KDefaultDrive,stat2);
       
   614 	test(stat1==KRequestPending && stat2==KRequestPending);
       
   615 	TheFs.NotifyDiskSpaceCancel(stat2);
       
   616 	test(stat1==KRequestPending && stat2==KErrCancel);
       
   617 	TheFs.NotifyDiskSpaceCancel(stat1);
       
   618 	test(stat1==KErrCancel);
       
   619 
       
   620 	if( !LffsDrive)
       
   621 		{
       
   622 		// now repeat with c: and removable drive
       
   623 		TheFs.NotifyDiskSpace(ThresholdSize,EDriveC,stat1);
       
   624 		TheFs.NotifyDiskSpace(ThresholdSize,RemovableDrive,stat2);
       
   625 		test(stat1==KRequestPending && stat2==KRequestPending);
       
   626 		TheFs.NotifyDiskSpaceCancel(stat1);
       
   627 		test(stat2==KRequestPending && stat1==KErrCancel);
       
   628 		TheFs.NotifyDiskSpaceCancel(stat2);
       
   629 		test(stat2==KErrCancel);
       
   630 		}
       
   631 	}
       
   632 
       
   633 void TestErrorConditions()
       
   634 //
       
   635 // test disk space notification requests return correct error value
       
   636 //
       
   637 	{
       
   638 	test.Next(_L("test error conditions"));
       
   639 	// attempt to set up disk space notification with a threshold of zero
       
   640 	TRequestStatus status;
       
   641 	TheFs.NotifyDiskSpace(0,KDefaultDrive,status);
       
   642 	test(status==KErrArgument);
       
   643 	// test on an empty drive
       
   644 	TheFs.NotifyDiskSpace(100,EDriveO,status);
       
   645 	test(status==KErrNotReady);
       
   646 	// test on a drive out of rance
       
   647 	TheFs.NotifyDiskSpace(100,27,status);
       
   648 	test(status==KErrBadName);
       
   649 	// new setup with threshold of one
       
   650 	TheFs.NotifyDiskSpace(1,KDefaultDrive,status);
       
   651 	test(status==KRequestPending);
       
   652 	TheFs.NotifyDiskSpaceCancel(status);
       
   653 	test(status==KErrCancel);
       
   654 	// and with a threshold > disk size
       
   655 	TheFs.NotifyDiskSpace(TheDiskSize+10,KDefaultDrive,status);
       
   656 	test(status==KErrArgument);
       
   657 	// now with a size of max size -1
       
   658 	TheFs.NotifyDiskSpace(TheDiskSize-1,KDefaultDrive,status);
       
   659 	test(status==KRequestPending);
       
   660 	TheFs.NotifyDiskSpaceCancel(status);
       
   661 	test(status==KErrCancel);
       
   662 	// set up mutiple requests and cancel one
       
   663 	TRequestStatus status2,status3;
       
   664 	TheFs.NotifyDiskSpace(TheDiskSize-10,KDefaultDrive,status);
       
   665 	TheFs.NotifyDiskSpace(TheDiskSize-10,KDefaultDrive,status2);
       
   666 	TheFs.NotifyDiskSpace(TheDiskSize-10,KDefaultDrive,status3);
       
   667 	test(status==KRequestPending&&status2==KRequestPending&&status3==KRequestPending);
       
   668 	TheFs.NotifyDiskSpaceCancel(status3);
       
   669 	test(status==KRequestPending&&status2==KRequestPending&&status3==KErrCancel);
       
   670 	// cancel the remaining ones
       
   671 	TheFs.NotifyDiskSpaceCancel();
       
   672 	test(status==KErrCancel&&status2==KErrCancel&&status3==KErrCancel);
       
   673 	}
       
   674 
       
   675 TInt GenerateMediaChange()
       
   676 	{
       
   677 	RLocalDrive d;
       
   678 	TBool flag=EFalse;
       
   679 	//Find the local drive number corresponding to removabledrive
       
   680 	TMediaSerialNumber serialNum;
       
   681 	TInt r = TheFs.GetMediaSerialNumber(serialNum, RemovableDrive);
       
   682 	if(r!= KErrNone)
       
   683 		return r;
       
   684 
       
   685 	TInt len = serialNum.Length();
       
   686 	test.Printf(_L("Serial number (len %d) :"), len);
       
   687 
       
   688 	TInt localDriveNum = -1;
       
   689 	for (TInt n=0; n<KMaxLocalDrives; n++)
       
   690 		{
       
   691 		r = d.Connect(n, flag);
       
   692 		if(r != KErrNone)
       
   693 			{
       
   694 			test.Printf(_L("drive %d: TBusLocalDrive::Connect() failed %d\n"), n, r);
       
   695 			continue;
       
   696 			}
       
   697 
       
   698 	    TLocalDriveCapsV5Buf capsBuf;
       
   699 	    TLocalDriveCapsV5& caps = capsBuf();
       
   700 		r = d.Caps(capsBuf);
       
   701 		if(r != KErrNone)
       
   702 			{
       
   703 			test.Printf(_L("drive %d: TBusLocalDrive::Caps() failed %d\n"), n, r);
       
   704 			continue;
       
   705 			}
       
   706 
       
   707 
       
   708 		TPtrC8 localSerialNum(caps.iSerialNum, caps.iSerialNumLength);
       
   709 		if (serialNum.Compare(localSerialNum) == 0)
       
   710 			{
       
   711 				localDriveNum = n;
       
   712 				d.Close();
       
   713 				break;
       
   714 			}
       
   715 
       
   716 		d.Close();
       
   717 		}
       
   718 	r =d.Connect(localDriveNum,flag);
       
   719 	if (r!=KErrNone)
       
   720 		return r;
       
   721 	d.ForceMediaChange();
       
   722 	d.Close();
       
   723 	return KErrNone;
       
   724 	}
       
   725 
       
   726 void TestDiskNotify()
       
   727 //
       
   728 // test functions that can result in disk change notification
       
   729 // format,scandrive, media change
       
   730 //
       
   731 	{
       
   732 	// make default directory
       
   733 	_LIT(defaultDir,"C:\\F32-TST\\");
       
   734 	TInt r=TheFs.MkDirAll(defaultDir);
       
   735 	test(r==KErrNone||r==KErrAlreadyExists);
       
   736 	// create the filler file
       
   737 	RFile file;
       
   738 	TFileName fileName=_L("C:");
       
   739 	fileName+=KFileFiller;
       
   740 	r=file.Create(TheFs,fileName,EFileShareAny|EFileWrite);
       
   741 	test(r==KErrNone);
       
   742 	TInt64 free=FreeDiskSpace(EDriveC);
       
   743 	// use up 16KB
       
   744 	FillDisk(file,free-16384,EDriveC);
       
   745 
       
   746 	// test formatting notifies clients on only specific drive
       
   747 	test.Next(_L("test formatting"));
       
   748 	TRequestStatus stat1, stat2;
       
   749 	TInt64 freeC=FreeDiskSpace(EDriveC);
       
   750 	TInt64 freeD=FreeDiskSpace(RemovableDrive);
       
   751 	TheFs.NotifyDiskSpace(freeC+1024,EDriveC,stat1);
       
   752 	TheFs.NotifyDiskSpace(freeD-1024,RemovableDrive,stat2);
       
   753 	test(stat1==KRequestPending && stat2==KRequestPending);
       
   754 	RFormat f;
       
   755 	TInt count;
       
   756 	r=f.Open(TheFs,RemovableDriveBuf,EQuickFormat,count);
       
   757 	test(r==KErrNone);
       
   758 	while(count)
       
   759 		{
       
   760 		r=f.Next(count);
       
   761 		test(r==KErrNone);
       
   762 		}
       
   763 	f.Close();
       
   764 	User::After(1000000);
       
   765 	User::WaitForRequest(stat2);
       
   766 	test(stat1==KRequestPending && stat2==KErrNone);
       
   767 	TheFs.NotifyDiskSpaceCancel(stat1);
       
   768 	test(stat1==KErrCancel);
       
   769 
       
   770 	// and create the test directory for the removable drive
       
   771 	TFileName fName=_L("");
       
   772 	fName+=RemovableDriveBuf;
       
   773 	fName+=_L("F32-TST\\");
       
   774 	r=TheFs.MkDirAll(fName);
       
   775 	test(r==KErrNone);
       
   776 
       
   777 	// test that a media change notifies clients on all drives
       
   778 	test.Next(_L("media change"));
       
   779 	freeC=FreeDiskSpace(EDriveC);
       
   780 	freeD=FreeDiskSpace(RemovableDrive);
       
   781 	test.Printf(_L("free space on drive %d = 0x%x\n"),EDriveC,freeC);
       
   782 	test.Printf(_L("free space on drive %d = 0x%x\n"),RemovableDrive,freeD);
       
   783 	TheFs.NotifyDiskSpace(freeC+1024,EDriveC,stat1);
       
   784 	TheFs.NotifyDiskSpace(freeD-1024,RemovableDrive,stat2);
       
   785 	test(stat1==KRequestPending && stat2==KRequestPending);
       
   786 //	UserSvr::ForceRemountMedia(ERemovableMedia0);
       
   787 	r = GenerateMediaChange();
       
   788 	if(r == KErrNone)
       
   789 		{
       
   790 		User::After(1000000);
       
   791 		User::WaitForRequest(stat2);
       
   792 		test(stat1==KRequestPending && stat2==KErrNone);
       
   793 		TheFs.NotifyDiskSpaceCancel(stat1);
       
   794 		test(stat1==KErrCancel);
       
   795 		}
       
   796 	else
       
   797 		{
       
   798 		test.Printf(_L("media change not supported, skipping this step\n"));
       
   799 		TheFs.NotifyDiskSpaceCancel(stat1);
       
   800 		test(stat1 == KErrCancel);
       
   801 		TheFs.NotifyDiskSpaceCancel(stat2);
       
   802 		test(stat2 == KErrCancel);
       
   803 		}
       
   804 
       
   805 	// test that scandrive notifies clients on only specific drives
       
   806 	test.Next(_L("scandrive"));
       
   807 	// first test that scandrive does not find any problems on the removable media
       
   808 	r=TheFs.ScanDrive(RemovableDriveBuf);
       
   809 	test(r==KErrNone);
       
   810 	// now set up disk space notification
       
   811 	freeC=FreeDiskSpace(EDriveC);
       
   812 	freeD=FreeDiskSpace(RemovableDrive);
       
   813 	test.Printf(_L("free space on drive %d = 0x%x\n"),EDriveC,freeC);
       
   814 	test.Printf(_L("free space on drive %d = 0x%x\n"),RemovableDrive,freeD);
       
   815 	TheFs.NotifyDiskSpace(freeC+8192,EDriveC,stat1);
       
   816 	TheFs.NotifyDiskSpace(freeD-8192,RemovableDrive,stat2);
       
   817 	test(stat1==KRequestPending && stat2==KRequestPending);
       
   818 	r=TheFs.ScanDrive(RemovableDriveBuf);
       
   819 	test(r==KErrNone);
       
   820 	User::After(1000000);
       
   821 	User::WaitForRequest(stat2);
       
   822 	test(stat1==KRequestPending && stat2==KErrNone);
       
   823 	TheFs.NotifyDiskSpaceCancel(stat1);
       
   824 	test(stat1==KErrCancel);
       
   825 
       
   826 	file.Close();
       
   827 	r=TheFs.Delete(fileName);
       
   828 	test(r==KErrNone);
       
   829 	if(gSessionPath[0]!=(TText)'C')
       
   830 		{
       
   831 		r=TheFs.RmDir(defaultDir);
       
   832 		test(r==KErrNone||r==KErrInUse);
       
   833 		}
       
   834 
       
   835 	}
       
   836 
       
   837 void TestFunctions()
       
   838 //
       
   839 // test some of the functions that may result in a change in free disk space
       
   840 // not testing all functions that may result in free disk space change since
       
   841 // change is dependent on the file system
       
   842 //
       
   843 	{
       
   844 	test.Next(_L("test disk space functions"));
       
   845 	// create the filler file
       
   846 	RFile file;
       
   847 	TInt r=file.Create(TheFs,KFileFiller,EFileShareAny|EFileWrite|EFileWriteDirectIO);
       
   848 	test(r==KErrNone);
       
   849 	TInt64 newSpace = FreeDiskSpace(KDefaultDrive)-8192;
       
   850 	FillDisk(file,newSpace,KDefaultDrive);
       
   851 
       
   852 	// check file write
       
   853 	test.Next(_L("check RFile:Write"));
       
   854 	TThreadTask task=ETaskFileWrite;
       
   855 	InitialiseForThread(task);
       
   856 	TInt64 free=FreeDiskSpace(KDefaultDrive);
       
   857 	TRequestStatus stat1;
       
   858 	TInt64 threshold=free-200;
       
   859 	TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
       
   860 	test(stat1==KRequestPending);
       
   861 	RThread thread;
       
   862 	r=thread.Create(_L("thread1"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
   863 	test(r==KErrNone);
       
   864 	thread.Resume();
       
   865 	User::WaitForRequest(stat1);
       
   866 	test(stat1==KErrNone);
       
   867 	free=FreeDiskSpace(KDefaultDrive);
       
   868 	test(free<threshold);
       
   869 	TRequestStatus deathStat;
       
   870 	thread.Logon( deathStat );
       
   871 	User::WaitForRequest( deathStat );
       
   872 	thread.Close();
       
   873 	CleanupForThread(task);
       
   874 
       
   875 	// check file set size
       
   876 	// setting file size on LFFS only uses a small amount of disk space for metadata
       
   877 	// so we skip this test for an LFFS drive
       
   878 	if( !LffsDrive )
       
   879 		{
       
   880 		test.Next(_L("check RFile:SetSize"));
       
   881 		task=ETaskFileSetSize;
       
   882 		InitialiseForThread(task);
       
   883 		free=FreeDiskSpace(KDefaultDrive);
       
   884 		threshold=free-100;
       
   885 		TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
       
   886 		test(stat1==KRequestPending);
       
   887 		r=thread.Create(_L("thread2"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
   888 		test(r==KErrNone);
       
   889 		TRequestStatus deathStat;
       
   890 		thread.Logon( deathStat );
       
   891 		thread.Resume();
       
   892 		User::WaitForRequest(stat1);
       
   893 		test(stat1==KErrNone);
       
   894 		free=FreeDiskSpace(KDefaultDrive);
       
   895 		test(free<threshold);
       
   896 		User::WaitForRequest( deathStat );
       
   897 		thread.Close();
       
   898 		CleanupForThread(task);
       
   899 		}
       
   900 
       
   901 	// check disk space notification does not occur when threshold not crossed
       
   902 	TInt64 newFree;
       
   903 	test.Next(_L("check RFile:SetSize with wrong threshold"));
       
   904 
       
   905 	User::After(1000000);	//put in due to thread latency
       
   906 
       
   907 	task=ETaskFileSetSize;
       
   908 	InitialiseForThread(task);
       
   909 	free=FreeDiskSpace(KDefaultDrive);
       
   910 	threshold=free+100;
       
   911 	TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
       
   912 	test(stat1==KRequestPending);
       
   913 	r=thread.Create(_L("thread3"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
   914 	test(r==KErrNone);
       
   915 	thread.Logon( deathStat );
       
   916 	thread.Resume();
       
   917 
       
   918 	User::After(1000000);
       
   919 
       
   920 	test(stat1==KRequestPending);
       
   921 	newFree=FreeDiskSpace(KDefaultDrive);
       
   922 /*
       
   923 	test.Printf(_L("threshold = %d and %d"),threshold.High(), threshold.Low());
       
   924 	test.Printf(_L("free = %d and %d"),free.High(), free.Low());
       
   925 	test.Printf(_L("newFree = %d and %d"),newFree.High(), newFree.Low());
       
   926 */
       
   927 	if(!LffsDrive)
       
   928 		test(free<threshold && newFree<free);
       
   929 	else
       
   930 		test(free<threshold);		//changing file size on lffs does not do anything
       
   931 
       
   932 	User::WaitForRequest( deathStat );
       
   933 	thread.Close();
       
   934 	CleanupForThread(task);
       
   935 	TheFs.NotifyDiskSpaceCancel(stat1);
       
   936 	test(stat1==KErrCancel);
       
   937 
       
   938 	// check for file delete
       
   939 	test.Next(_L("check RFs::Delete"));
       
   940 	task=ETaskDelete;
       
   941 	InitialiseForThread(task);
       
   942 	free=FreeDiskSpace(KDefaultDrive);
       
   943 	threshold=free+300;
       
   944 	TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
       
   945 	test(stat1==KRequestPending);
       
   946 	r=thread.Create(_L("thread4"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
   947 	test(r==KErrNone);
       
   948 	thread.Logon( deathStat );
       
   949 	thread.Resume();
       
   950 	User::WaitForRequest(stat1);
       
   951 	test(stat1==KErrNone);
       
   952 	free=FreeDiskSpace(KDefaultDrive);
       
   953 	test(free>threshold);
       
   954 	User::WaitForRequest( deathStat );
       
   955 	thread.Close();
       
   956 	CleanupForThread(task);
       
   957 
       
   958 	// check for replace with threshold too high
       
   959 	test.Next(_L("check RFs::Replace with threshold too high"));
       
   960 
       
   961     if( LffsDrive )
       
   962 	{
       
   963 	    test.Printf( _L("Skipped.... test isn't consistent on LFFS drive\n") );
       
   964 	}
       
   965     else
       
   966 	{
       
   967         task=ETaskReplace;
       
   968 	    InitialiseForThread(task);
       
   969 	    free=FreeDiskSpace(KDefaultDrive);
       
   970     #if defined(__WINS__)
       
   971 	    threshold=free + gMinFileSize * 16 + 2048;		// 512 * 16 + 2K = 10K
       
   972     #else
       
   973 	    if(LffsDrive )
       
   974 		    threshold=free + (gMinFileSize << 4) + 2048;	// 512 * 16 + 2K = 10K
       
   975 	    else
       
   976 		    threshold=free + gMinFileSize * 9 + 392;	// 512 * 9 + 392 = 5000;
       
   977     #endif
       
   978 
       
   979 	    TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
       
   980 	    test(stat1==KRequestPending);
       
   981 
       
   982 	    r=thread.Create(_L("thread5"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
   983 	    test(r==KErrNone);
       
   984 	    thread.Logon( deathStat );
       
   985 	    thread.Resume();
       
   986 
       
   987 	    User::After(1000000);
       
   988 	    test(stat1==KRequestPending);
       
   989 	    newFree=FreeDiskSpace(KDefaultDrive);
       
   990 	    test(newFree<threshold && free<newFree);
       
   991 	    TheFs.NotifyDiskSpaceCancel();
       
   992 	    test(stat1==KErrCancel);
       
   993 	    User::WaitForRequest( deathStat );
       
   994 	    thread.Close();
       
   995 	    CleanupForThread(task);
       
   996 
       
   997 
       
   998 	    // check for replace
       
   999 	    test.Next(_L("check RFs:Replace"));
       
  1000 	    task=ETaskReplace;
       
  1001 	    InitialiseForThread(task);
       
  1002 	    free=FreeDiskSpace(KDefaultDrive);
       
  1003 	    threshold=free+200;
       
  1004 	    TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
       
  1005 	    test(stat1==KRequestPending);
       
  1006 	    r=thread.Create(_L("thread6"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1007 	    test(r==KErrNone);
       
  1008 	    thread.Logon( deathStat );
       
  1009 	    thread.Resume();
       
  1010 	    User::WaitForRequest(stat1);
       
  1011 	    //User::After(1000000);
       
  1012 	    test(stat1==KErrNone);
       
  1013 	    User::WaitForRequest( deathStat );
       
  1014 	    test(deathStat==KErrNone);
       
  1015 	    thread.Close();
       
  1016 	    CleanupForThread(task);
       
  1017 	    free=FreeDiskSpace(KDefaultDrive);
       
  1018 	    test(free>threshold);
       
  1019     }
       
  1020 
       
  1021 	// check that CSessionFS::iTheDrive is set in subsession calls
       
  1022 	test.Next(_L("Check iTheDrive and subsessions"));
       
  1023 	if( LffsDrive )
       
  1024 		{
       
  1025 		test.Printf( _L("Skipped.... test not done on LFFS drive\n") );
       
  1026 		}
       
  1027 	else
       
  1028 		{
       
  1029 		RFile f2;
       
  1030 #if defined(__WINS__)
       
  1031 		_LIT(someFile,"X:\\abcdef");
       
  1032 #else
       
  1033 		TBuf<10> someFile=_L("?:\\abcdef");
       
  1034 		TChar c;
       
  1035 		TInt r=RFs::DriveToChar(RemovableDrive,c);
       
  1036 		test(r==KErrNone);
       
  1037 		someFile[0]=(TText)c;
       
  1038 #endif
       
  1039 		_LIT(someDir,"C:\\1234\\");
       
  1040 
       
  1041 		r=f2.Create(TheFs,someFile,EFileShareAny|EFileWrite);
       
  1042 		test(r==KErrNone);
       
  1043 		r=TheFs.MkDir(someDir);
       
  1044 		test(r==KErrNone);
       
  1045 		TRequestStatus stat2;
       
  1046 		TInt64 freeC=FreeDiskSpace(EDriveC);
       
  1047 		TInt64 freeD=FreeDiskSpace(RemovableDrive);
       
  1048 		TheFs.NotifyDiskSpace(freeC-4097,EDriveC,stat1);
       
  1049 		TheFs.NotifyDiskSpace(freeD-4097,RemovableDrive,stat2);
       
  1050 		test(stat1==KRequestPending && stat2==KRequestPending);
       
  1051 		// before fix this would result in iTheDrive not being updated in next subsession call
       
  1052 		// therefore this could would not result in a disk space notification
       
  1053 		r=f2.SetSize(8192);
       
  1054 		test(r==KErrNone);
       
  1055 		User::After(1000000);
       
  1056 		User::WaitForRequest(stat2);
       
  1057 
       
  1058 		if (stat2!=KErrNone)
       
  1059 			test.Printf(_L("stat2=%d\n"),stat2.Int());
       
  1060 		test(stat2==KErrNone);
       
  1061 		if (stat1!=KRequestPending)
       
  1062 			test.Printf(_L("stat1=%d\n"),stat1.Int());
       
  1063 		test(stat1==KRequestPending);
       
  1064 
       
  1065 		f2.Close();
       
  1066 		TheFs.NotifyDiskSpaceCancel();
       
  1067 		test(stat1==KErrCancel);
       
  1068 		r=TheFs.Delete(someFile);
       
  1069 		test(r==KErrNone);
       
  1070 		r=TheFs.RmDir(someDir);
       
  1071 		test(r==KErrNone);
       
  1072 		}
       
  1073 
       
  1074 	file.Close();
       
  1075 	r=TheFs.Delete(KFileFiller);
       
  1076 	test(r==KErrNone);
       
  1077 	}
       
  1078 
       
  1079 
       
  1080 
       
  1081 void TestLffsFunctions()
       
  1082 //
       
  1083 // LFFS-specific tests for some functions which may cause a disk
       
  1084 // space change
       
  1085 //
       
  1086 //
       
  1087 	{
       
  1088 	test.Next(_L("test LFFS disk space functions"));
       
  1089 	// create the filler file
       
  1090 	RFile file;
       
  1091 	TInt r=file.Create(TheFs,KFileFiller,EFileShareAny|EFileWrite|EFileWriteDirectIO);
       
  1092 	test(r==KErrNone);
       
  1093 	TInt64 newSpace = FreeDiskSpace(KDefaultDrive)-8192;
       
  1094 	FillDisk(file,newSpace,KDefaultDrive);
       
  1095 
       
  1096 
       
  1097 	// check file create
       
  1098 	// Creating a file will always allocate space for the inode
       
  1099 	test.Next(_L("check RFile:Create"));
       
  1100 	TThreadTask task=ETaskFileCreateLffs;
       
  1101 	InitialiseForThread(task);
       
  1102 	TInt64 free=FreeDiskSpace(KDefaultDrive);
       
  1103 	TInt64 threshold1=free-64;
       
  1104 	TInt64 threshold2=free-KFileSize3;
       
  1105 	TRequestStatus stat1, stat2;
       
  1106 	TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
       
  1107 	TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
       
  1108 	test(stat1==KRequestPending && stat2==KRequestPending);
       
  1109 	RThread thread;
       
  1110 	r=thread.Create(_L("thread7"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1111 	test(r==KErrNone);
       
  1112 	TRequestStatus deathStat;
       
  1113 	thread.Logon( deathStat );
       
  1114 	thread.Resume();
       
  1115 	User::WaitForRequest(stat1);
       
  1116 	test(stat1==KErrNone);
       
  1117 	free=FreeDiskSpace(KDefaultDrive);
       
  1118 	test(free<threshold1);
       
  1119 	test(stat2==KRequestPending);
       
  1120 	test(free>threshold2);
       
  1121 	TheFs.NotifyDiskSpaceCancel(stat2);
       
  1122 	User::WaitForRequest(stat2);
       
  1123 	test(stat2==KErrCancel);
       
  1124 	User::WaitForRequest( deathStat );
       
  1125 	thread.Close();
       
  1126 	CleanupForThread(task);
       
  1127 
       
  1128 	TInt64 threshold3;
       
  1129 	TRequestStatus stat3;
       
  1130 	RFile file2;
       
  1131 	// don't test for wins urel since cant use RFs::ControlIo
       
  1132 #if defined(_DEBUG)
       
  1133 	// check background thread notification
       
  1134 	test.Next(_L("check Background thread notification"));
       
  1135 	task=ETaskSpin; // create thread to block background thread
       
  1136 	InitialiseForThread(task);
       
  1137 	free=FreeDiskSpace(KDefaultDrive);
       
  1138 	threshold1=free-64;		// this should occur when we create test file
       
  1139 	threshold2=free+9750;		// some impossible value
       
  1140 	threshold3=free+10000;	// some other impossible value that will never happen
       
  1141 	TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
       
  1142 	TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
       
  1143 	TheFs.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
       
  1144 	test(stat1==KRequestPending && stat2==KRequestPending && stat3==KRequestPending);
       
  1145 	r=thread.Create(_L("thread8"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1146 	test(r==KErrNone);
       
  1147 	thread.Logon( deathStat );
       
  1148 	thread.SetPriority( EPriorityLess );
       
  1149 	thread.Resume();	// start spinning, blocks background thread
       
  1150 	// request background thread to notify a daft value
       
  1151     TPckgBuf<TInt64> cBuf;
       
  1152 	cBuf() = threshold2;
       
  1153  	// Hard code the value of ECioBackgroundNotifyDiskSize.
       
  1154  	// Although the value is enumerated in f32\slffs\lffs_controlio.h this header file is being
       
  1155  	// removed from the release codeline but retained in the base team development codeline.
       
  1156 	#define ECioBackgroundNotifyDiskSize 10016
       
  1157 	r = TheFs.ControlIo(GetDriveLFFS(), ECioBackgroundNotifyDiskSize, cBuf);
       
  1158 	test( KErrNone==r );
       
  1159 	// create a  file to force some roll-forward
       
  1160 	r=file2.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
       
  1161 	test(r==KErrNone);
       
  1162 	User::WaitForRequest(stat1);
       
  1163 	test(stat1==KErrNone);
       
  1164 	test(stat2==KRequestPending);
       
  1165 	test(stat3==KRequestPending);
       
  1166 	// kill the spinner thread to allow the background thread to execute
       
  1167 	thread.Kill(KErrNone);
       
  1168 	User::WaitForRequest( deathStat );
       
  1169 	thread.Close();
       
  1170 	// wait for the notifier
       
  1171 	User::WaitForRequest(stat2);
       
  1172 	test( stat2==KErrNone );
       
  1173 	test( stat3==KRequestPending);
       
  1174 	TheFs.NotifyDiskSpaceCancel(stat3);
       
  1175 	User::WaitForRequest(stat3);
       
  1176 	test(stat3==KErrCancel);
       
  1177 	CleanupForThread(task);
       
  1178 	file2.Close();
       
  1179 	TheFs.Delete( KTestFile1 );
       
  1180 #endif
       
  1181 
       
  1182 	// check background thread notification again, this time we won't request
       
  1183 	// a special value - check that it notifies normally
       
  1184 	test.Next(_L("check Background thread notification again"));
       
  1185 	task=ETaskSpin; // create thread to block background thread
       
  1186 	InitialiseForThread(task);
       
  1187 	free=FreeDiskSpace(KDefaultDrive);
       
  1188 	threshold1=free-64;		// this should occur when we create test file
       
  1189 	threshold2=free+9750;		// some impossible value
       
  1190 	threshold3=free+10000;	// some other impossible value that will never happen
       
  1191 	TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
       
  1192 	TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
       
  1193 	TheFs.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
       
  1194 	test(stat1==KRequestPending && stat2==KRequestPending && stat3==KRequestPending);
       
  1195 	r=thread.Create(_L("thread9"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1196 	test(r==KErrNone);
       
  1197 	thread.Logon( deathStat );
       
  1198 	thread.SetPriority( EPriorityLess );
       
  1199 	thread.Resume();	// start spinning, blocks background thread
       
  1200 	// create a  file to force some roll-forward
       
  1201 	r=file2.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
       
  1202 	test(r==KErrNone);
       
  1203 	User::WaitForRequest(stat1);
       
  1204 	test(stat1==KErrNone);
       
  1205 	test(stat2==KRequestPending);
       
  1206 	test(stat3==KRequestPending);
       
  1207 	// kill the spinner thread to allow the background thread to execute
       
  1208 	thread.Kill(KErrNone);
       
  1209 	User::WaitForRequest( deathStat );
       
  1210 	thread.Close();
       
  1211 	// wait for the notifier
       
  1212 	test( stat2==KRequestPending );
       
  1213 	test( stat3==KRequestPending);
       
  1214 	TheFs.NotifyDiskSpaceCancel(stat2);
       
  1215 	User::WaitForRequest(stat2);
       
  1216 	test(stat2==KErrCancel);
       
  1217 	TheFs.NotifyDiskSpaceCancel(stat3);
       
  1218 	User::WaitForRequest(stat3);
       
  1219 	test(stat3==KErrCancel);
       
  1220 	CleanupForThread(task);
       
  1221 	file2.Close();
       
  1222 	TheFs.Delete( KTestFile1 );
       
  1223 
       
  1224 
       
  1225 	file.Close();
       
  1226 	r=TheFs.Delete(KFileFiller);
       
  1227 	test(r==KErrNone);
       
  1228 	}
       
  1229 
       
  1230 
       
  1231 void TestMultiple()
       
  1232 //
       
  1233 // test muliple requests and multiple sessions
       
  1234 //
       
  1235 	{
       
  1236 	// create the filler file
       
  1237 	RFile file;
       
  1238 	TInt r=file.Create(TheFs,KFileFiller,EFileShareAny|EFileWrite|EFileWriteDirectIO);
       
  1239 	test(r==KErrNone);
       
  1240 	TInt64 free=FreeDiskSpace(KDefaultDrive);
       
  1241 	TInt64 freeSpaceLeft = gMinFileSize << 4;	// 512 * 2^4 = 512 * 16 = 8K
       
  1242 	FillDisk(file,free-freeSpaceLeft,KDefaultDrive);
       
  1243 	TInt size;
       
  1244 	r=file.Size(size);
       
  1245 	test(r==KErrNone);
       
  1246 	test(size>1024);
       
  1247 	test.Printf(_L("filler file size=0x%x\n"),size);
       
  1248 
       
  1249 	// test multiple requests
       
  1250 	test.Next(_L("test multiple requests"));
       
  1251 	TThreadTask task = ETaskFileWrite4KB;
       
  1252 	InitialiseForThread(task);
       
  1253 	free=FreeDiskSpace(KDefaultDrive);
       
  1254 	TInt64 threshold1=free-gMinFileSize;	// 512;
       
  1255 	TInt64 threshold2=free - (gMinFileSize << 2);	// 512 * 4 = 2048;
       
  1256 #if defined(__WINS__)
       
  1257 	TInt64 threshold3=free-70000;	//NTFS over-allocates then reduces when file closed
       
  1258 #else
       
  1259 	TInt64 threshold3=free - (gMinFileSize << 5);	// 512 * 2^5 = 512 * 32 = 16K
       
  1260 #endif
       
  1261 	TRequestStatus stat1,stat2,stat3;
       
  1262 	TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
       
  1263 	TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
       
  1264 	TheFs.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
       
  1265 	test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
       
  1266 	RThread thread;
       
  1267 	r=thread.Create(_L("thread1"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1268 	test(r==KErrNone);
       
  1269 	TRequestStatus deathStat;
       
  1270 	thread.Logon( deathStat );
       
  1271 	thread.Resume();
       
  1272 	User::After(1000000);
       
  1273 	User::WaitForRequest(stat1);
       
  1274 	User::WaitForRequest(stat2);
       
  1275 	test(stat1==KErrNone && stat2==KErrNone);
       
  1276 	test(stat3==KRequestPending);
       
  1277 	free=FreeDiskSpace(KDefaultDrive);
       
  1278 	test(free<threshold1 && free<threshold2 && free>threshold3);
       
  1279 	TheFs.NotifyDiskSpaceCancel(stat3);
       
  1280 	test(stat3==KErrCancel);
       
  1281 	User::WaitForRequest( deathStat );
       
  1282 	thread.Close();
       
  1283 	CleanupForThread(task);
       
  1284 
       
  1285 	// test multiple requests again
       
  1286 	test.Next(_L("test multiple requests again"));
       
  1287 	if( LffsDrive )
       
  1288 		{
       
  1289 		// SetSize doesn't use disk space on LFFS
       
  1290 		test.Printf( _L("test skipped on LFFS drive\n") );
       
  1291 		}
       
  1292 	else
       
  1293 		{
       
  1294 		task=ETaskFileSetSize;
       
  1295 		InitialiseForThread(task);	// this also does initialisation for task2
       
  1296 		free=FreeDiskSpace(KDefaultDrive);
       
  1297 		threshold1 = free + (gMinFileSize << 1);	// 512 * 2 = 1024
       
  1298 		threshold2 = free + (gMinFileSize * 12);	// 512 * 12 = 6144
       
  1299 		threshold3 = free - (gMinFileSize << 1);	// 512 * 2 = 1024;
       
  1300 		TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
       
  1301 		TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
       
  1302 		TheFs.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
       
  1303 		test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
       
  1304 		r=thread.Create(_L("thread2"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1305 		test(r==KErrNone);
       
  1306 		thread.Logon( deathStat );
       
  1307 		thread.Resume();
       
  1308 		User::After(10000);
       
  1309 		User::WaitForRequest(stat3);
       
  1310 		test(stat3==KErrNone && stat1==KRequestPending && stat2==KRequestPending);
       
  1311 		free=FreeDiskSpace(KDefaultDrive);
       
  1312 		test(free<threshold1);
       
  1313 		User::WaitForRequest( deathStat );
       
  1314 		thread.Close();
       
  1315 		CleanupForThread(task);
       
  1316 		if(!IsWinsCDrive(KDefaultDrive))
       
  1317 			{
       
  1318 			free=FreeDiskSpace(KDefaultDrive);
       
  1319 			test(stat1==KRequestPending && stat2==KRequestPending);
       
  1320 			file.SetSize(size - (gMinFileSize << 2));	// 512 * 4 = 2048
       
  1321 			free=FreeDiskSpace(KDefaultDrive);
       
  1322 			User::After(1000000);
       
  1323 			User::WaitForRequest(stat1);
       
  1324 			//User::WaitForRequest(stat2);
       
  1325 			test(stat1==KErrNone && stat2==KRequestPending);
       
  1326 			free=FreeDiskSpace(KDefaultDrive);
       
  1327 			test(free>threshold1 && free<threshold2);
       
  1328 			TheFs.NotifyDiskSpaceCancel();
       
  1329 			test(stat2==KErrCancel);
       
  1330 			}
       
  1331 		else
       
  1332 			{
       
  1333 			TheFs.NotifyDiskSpaceCancel();
       
  1334 			test(stat1==KErrCancel&&stat2==KErrCancel&&stat3==KErrNone);
       
  1335 			}
       
  1336 		}
       
  1337 
       
  1338 	// test multiple sessions all notified on disk space change
       
  1339 	test.Next(_L("test multiple sessions on same drive"));
       
  1340 	RFs ses2,ses3;
       
  1341 	r=ses2.Connect();
       
  1342 	test(r==KErrNone);
       
  1343 	r=ses3.Connect();
       
  1344 	test(r==KErrNone);
       
  1345 	r=ses2.SetSessionPath(gSessionPath);
       
  1346 	test(r==KErrNone);
       
  1347 	r=ses3.SetSessionPath(gSessionPath);
       
  1348 	test(r==KErrNone);
       
  1349 	task=ETaskFileReplace;
       
  1350 	InitialiseForThread(task);
       
  1351 	free=FreeDiskSpace(KDefaultDrive);
       
  1352 	test.Printf(_L("free space on default drive = 0x%x\n"),free);
       
  1353 	threshold1=free+gMinFileSize;			// 512
       
  1354 	threshold2=free+(gMinFileSize << 1);	// 1024;
       
  1355 	threshold3=free+(gMinFileSize << 2);	// 2048;
       
  1356 	TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
       
  1357 	ses2.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
       
  1358 	ses3.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
       
  1359 	test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
       
  1360 	r=thread.Create(_L("thread3"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1361 	test(r==KErrNone);
       
  1362 	thread.Logon( deathStat );
       
  1363 	thread.Resume();
       
  1364 	User::After(1000000);
       
  1365 	User::WaitForRequest(stat1);
       
  1366 	User::WaitForRequest(stat2);
       
  1367 	User::WaitForRequest(stat3);
       
  1368 	test(stat1==KErrNone && stat2==KErrNone && stat3==KErrNone);
       
  1369 	free=FreeDiskSpace(KDefaultDrive);
       
  1370 	test(free>threshold1 && free>threshold2 && free>threshold3);
       
  1371 	User::WaitForRequest( deathStat );
       
  1372 	thread.Close();
       
  1373 	CleanupForThread(task);
       
  1374 
       
  1375 	// test NotifyDiskSpaceCancel()
       
  1376 	test.Next(_L("test RFs:NotifyDiskSpaceCancel"));
       
  1377 	free=FreeDiskSpace(KDefaultDrive);
       
  1378 	TheFs.NotifyDiskSpace(free-100,KDefaultDrive,stat1);
       
  1379 	ses2.NotifyDiskSpace(free-100,KDefaultDrive,stat2);
       
  1380 	ses3.NotifyDiskSpace(free-100,KDefaultDrive,stat3);
       
  1381 	test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
       
  1382 	TheFs.NotifyDiskSpaceCancel();
       
  1383 	test(stat1==KErrCancel&&stat2==KRequestPending&&stat3==KRequestPending);
       
  1384 	ses2.NotifyDiskSpaceCancel(stat2);
       
  1385 	test(stat2==KErrCancel&&stat3==KRequestPending);
       
  1386 	ses3.NotifyDiskSpaceCancel();
       
  1387 	test(stat3==KErrCancel);
       
  1388 
       
  1389 	if( !LffsDrive )
       
  1390 		{
       
  1391 		TInt sessionDrive;
       
  1392 		r=RFs::CharToDrive(gSessionPath[0],sessionDrive);
       
  1393 		test(r==KErrNone);
       
  1394 		if(sessionDrive!=RemovableDrive)
       
  1395 			{
       
  1396 			// first create a file on the removable drive
       
  1397 			RFile file2;
       
  1398 			TFileName file2name=RemovableDriveBuf;
       
  1399 			file2name+=_L("F32-TST\\testfile1");
       
  1400 			TheFs.Delete(file2name);
       
  1401 			r=file2.Create(TheFs,file2name,EFileShareAny|EFileWrite);
       
  1402 			test(r==KErrNone);
       
  1403 			r=file2.SetSize(KFileSize3);
       
  1404 			test(r==KErrNone);
       
  1405 			// test multiple sessions not notified on disk space change on wrong drive
       
  1406 			test.Next(_L("test multiple sessions on different drives"));
       
  1407 			task=ETaskFileReplace;
       
  1408 			InitialiseForThread(task);
       
  1409 			TInt64 freeDef=FreeDiskSpace(KDefaultDrive);
       
  1410 			TInt64 freeRem=FreeDiskSpace(RemovableDrive);
       
  1411 			threshold1=freeDef + (gMinFileSize << 1);	// 1024;
       
  1412 			threshold2=freeRem + (gMinFileSize << 1);	// 1024;
       
  1413 			TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
       
  1414 			ses2.NotifyDiskSpace(threshold2,RemovableDrive,stat2);
       
  1415 			test(stat1==KRequestPending&&stat2==KRequestPending);
       
  1416 			r=thread.Create(_L("thread4"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1417 			test(r==KErrNone);
       
  1418 			thread.Logon( deathStat );
       
  1419 			thread.Resume();
       
  1420 			User::After(1000000);
       
  1421 			User::WaitForRequest(stat1);
       
  1422 			test(stat1==KErrNone && stat2==KRequestPending);
       
  1423 			free=FreeDiskSpace(KDefaultDrive);
       
  1424 			test(free>threshold1);
       
  1425 			User::WaitForRequest( deathStat );
       
  1426 			thread.Close();
       
  1427 			CleanupForThread(task);
       
  1428 			TheFs.NotifyDiskSpaceCancel(stat2);
       
  1429 			test(stat2==KRequestPending);
       
  1430 			ses2.NotifyDiskSpaceCancel(stat2);
       
  1431 			test(stat2==KErrCancel);
       
  1432 			file2.Close();
       
  1433 			r=TheFs.Delete(file2name);
       
  1434 			test(r==KErrNone);
       
  1435 			}
       
  1436 		}
       
  1437 
       
  1438 	ses2.Close();
       
  1439 	ses3.Close();
       
  1440 
       
  1441 
       
  1442 	file.Close();
       
  1443 	r=TheFs.Delete(KFileFiller);
       
  1444 	test(r==KErrNone);
       
  1445 
       
  1446 	}
       
  1447 
       
  1448 
       
  1449 void TestLffsMultiple()
       
  1450 //
       
  1451 // test muliple requests and multiple sessions speicifcally for LFFS drive
       
  1452 //
       
  1453 	{
       
  1454 	// create the filler file
       
  1455 	RFile file;
       
  1456 	TInt r=file.Create(TheFs,KFileFiller,EFileShareAny|EFileWrite|EFileWriteDirectIO);
       
  1457 	test(r==KErrNone);
       
  1458 	TInt64 free=FreeDiskSpace(KDefaultDrive);
       
  1459 	FillDisk(file,free-8192,KDefaultDrive);
       
  1460 	TInt size;
       
  1461 	r=file.Size(size);
       
  1462 	test(r==KErrNone);
       
  1463 	test.Printf(_L("filler file size=0x%x\n"),size);
       
  1464 
       
  1465 
       
  1466 	// test multiple requests again
       
  1467 	test.Next(_L("test multiple requests on LFFS") );
       
  1468 
       
  1469 	TThreadTask task=ETaskFileCreateLffs;
       
  1470 	InitialiseForThread(task);	// this also does initialisation for task2
       
  1471 	free=FreeDiskSpace(KDefaultDrive);
       
  1472 	TInt64 threshold1=free+8192;
       
  1473 	TInt64 threshold2=free+700; //increased threshold as LFFS, unpredicatably, can release drive space
       
  1474 	TInt64 threshold3=free-64;
       
  1475 	TRequestStatus stat1, stat2, stat3;
       
  1476 //test.Printf(_L("set up notifiers"));
       
  1477 	TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
       
  1478 	TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
       
  1479 	TheFs.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
       
  1480 	test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
       
  1481 	RThread thread;
       
  1482 	r=thread.Create(_L("thread10"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1483 	test(r==KErrNone);
       
  1484 	TRequestStatus deathStat;
       
  1485 	thread.Logon( deathStat );
       
  1486 //	test.Printf(_L("Resuming other thread"));
       
  1487 	thread.Resume();
       
  1488 	User::After(10000);
       
  1489 	User::WaitForRequest(stat3);
       
  1490 	test(stat3==KErrNone && stat1==KRequestPending && stat2==KRequestPending);
       
  1491 	free=FreeDiskSpace(KDefaultDrive);
       
  1492 	test(free<threshold1);
       
  1493 	User::WaitForRequest( deathStat );
       
  1494 	thread.Close();
       
  1495 	CleanupForThread(task);
       
  1496 	free=FreeDiskSpace(KDefaultDrive);
       
  1497 //	test.Printf(_L("free =%d and %d"),free.Low(), free.High());
       
  1498 //	test.Printf(_L("stat1=%d, stat2=%d"),stat1,stat2);
       
  1499 	test(stat1==KRequestPending && stat2==KRequestPending);
       
  1500 	file.SetSize(6144);
       
  1501 	User::After(1000000);
       
  1502 	User::WaitForRequest(stat2);
       
  1503 	test(stat1==KRequestPending && stat2==KErrNone);
       
  1504 	free=FreeDiskSpace(KDefaultDrive);
       
  1505 	test(free<threshold1 && free>threshold2);
       
  1506 	TheFs.NotifyDiskSpaceCancel();
       
  1507 	User::WaitForRequest( stat1 );
       
  1508 	test(stat1==KErrCancel);
       
  1509 
       
  1510 
       
  1511 
       
  1512 	TInt sessionDrive;
       
  1513 	r=RFs::CharToDrive(gSessionPath[0],sessionDrive);
       
  1514 	test(r==KErrNone);
       
  1515 	if(sessionDrive!=EDriveC)
       
  1516 		{
       
  1517 		// test multiple sessions not notified on disk space change on wrong drive
       
  1518 		test.Next(_L("test multiple sessions on different drives"));
       
  1519 
       
  1520 		RFs ses2,ses3;
       
  1521 		r=ses2.Connect();
       
  1522 		test(r==KErrNone);
       
  1523 		r=ses3.Connect();
       
  1524 		test(r==KErrNone);
       
  1525 		r=ses2.SetSessionPath(gSessionPath);
       
  1526 		test(r==KErrNone);
       
  1527 		r=ses3.SetSessionPath(gSessionPath);
       
  1528 		test(r==KErrNone);
       
  1529 
       
  1530 		// first create a file on the C:\ drive
       
  1531 		RFile file2;
       
  1532 		TFileName file2name=_L("C:\\");
       
  1533 		file2name+=_L("F32-TST\\");
       
  1534 		r=TheFs.MkDir(file2name);
       
  1535 		test( KErrNone==r || KErrAlreadyExists==r );
       
  1536 		file2name+=_L("testfile1");
       
  1537 		TheFs.Delete(file2name);
       
  1538 		r=file2.Create(TheFs,file2name,EFileShareAny|EFileWrite);
       
  1539 		test(r==KErrNone);
       
  1540 		WriteToFile( file2, KFileSize3 );
       
  1541 
       
  1542 		task=ETaskFileReplace;
       
  1543 		InitialiseForThread(task);
       
  1544 		TInt64 freeLffs=FreeDiskSpace(KDefaultDrive);
       
  1545 		TInt64 freeD=FreeDiskSpace(EDriveC);
       
  1546 		threshold1=freeLffs+1024;
       
  1547 		threshold2=freeD+1024;
       
  1548 		TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
       
  1549 		ses2.NotifyDiskSpace(threshold2,EDriveC,stat2);
       
  1550 		test(stat1==KRequestPending&&stat2==KRequestPending);
       
  1551 		r=thread.Create(_L("thread11"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1552 		test(r==KErrNone);
       
  1553 		thread.Logon( deathStat );
       
  1554 		thread.Resume();
       
  1555 		User::After(1000000);
       
  1556 		User::WaitForRequest(stat1);
       
  1557 		test(stat1==KErrNone && stat2==KRequestPending);
       
  1558 		free=FreeDiskSpace(KDefaultDrive);
       
  1559 		test(free>threshold1);
       
  1560 		User::WaitForRequest( deathStat );
       
  1561 		thread.Close();
       
  1562 		CleanupForThread(task);
       
  1563 		TheFs.NotifyDiskSpaceCancel(stat2);
       
  1564 		test(stat2==KRequestPending);
       
  1565 		ses2.NotifyDiskSpaceCancel(stat2);
       
  1566 		User::WaitForRequest( stat2 );
       
  1567 		test(stat2==KErrCancel);
       
  1568 		file2.Close();
       
  1569 		r=TheFs.Delete(file2name);
       
  1570 		test(r==KErrNone);
       
  1571 		ses2.Close();
       
  1572 		ses3.Close();
       
  1573 		}
       
  1574 
       
  1575 
       
  1576 
       
  1577 	file.Close();
       
  1578 	r=TheFs.Delete(KFileFiller);
       
  1579 	test(r==KErrNone);
       
  1580 
       
  1581 	}
       
  1582 
       
  1583 
       
  1584 void TestChangeNotification()
       
  1585 //
       
  1586 // test that disk space notification works with (extended) change notification
       
  1587 //
       
  1588 	{
       
  1589 	// create a filler file
       
  1590 	RFile file;
       
  1591 	TInt r=file.Create(TheFs,KFileFiller,EFileShareAny|EFileWrite|EFileWriteDirectIO);
       
  1592 	test(r==KErrNone);
       
  1593 	TInt64 free=FreeDiskSpace(KDefaultDrive);
       
  1594 	// use 8KB in filler file
       
  1595 	FillDisk(file,free-8192,KDefaultDrive);
       
  1596 
       
  1597 	// test change notification when no disk space change
       
  1598 	test.Next(_L("test change notification"));
       
  1599 	TThreadTask task = ETaskNoChange1;
       
  1600 	InitialiseForThread(task);
       
  1601 	free=FreeDiskSpace(KDefaultDrive);
       
  1602 	TInt64 threshold1=free+gMinFileSize;
       
  1603 	TInt64 threshold2=free-gMinFileSize;
       
  1604 	TRequestStatus stat1,stat2,stat3;
       
  1605 	TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);		//more free space becoming available
       
  1606 	TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
       
  1607 	TheFs.NotifyChange(ENotifyAll,stat3);
       
  1608 	test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
       
  1609 	RThread thread;
       
  1610 	r=thread.Create(_L("thread1"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1611 	test(r==KErrNone);
       
  1612 	TRequestStatus deathStat;
       
  1613 	thread.Logon( deathStat );
       
  1614 	thread.Resume();
       
  1615 	User::After(1000000);
       
  1616 	User::WaitForRequest(stat3);
       
  1617 	if(!LffsDrive)
       
  1618 		test(stat1==KRequestPending && stat2==KRequestPending && stat3==KErrNone);
       
  1619 	else
       
  1620 		test(stat2==KRequestPending && stat3==KErrNone);	//As below
       
  1621 
       
  1622 	TheFs.NotifyDiskSpaceCancel();
       
  1623 	if(!LffsDrive)
       
  1624 		test(stat1==KErrCancel && stat2==KErrCancel);
       
  1625 	else
       
  1626 		test(stat2==KErrCancel);	//is invalid for LFFS as can free up space un expectedly
       
  1627 
       
  1628 	User::WaitForRequest( deathStat );
       
  1629 	thread.Close();
       
  1630 	CleanupForThread(task);
       
  1631 
       
  1632 	// Have three different sessions
       
  1633 	// do an operation that will cause the change notification
       
  1634 	// and disk change notification to be signalled
       
  1635 	test.Next(_L(" test change notification and disk space notification"));
       
  1636 	RFs session2,session3;
       
  1637 	r=session2.Connect();
       
  1638 	test(r==KErrNone);
       
  1639 	r=session3.Connect();
       
  1640 	test(r==KErrNone);
       
  1641 	r=session2.SetSessionPath(gSessionPath);
       
  1642 	test(r==KErrNone);
       
  1643 	r=session3.SetSessionPath(gSessionPath);
       
  1644 	test(r==KErrNone);
       
  1645 	task=ETaskFileWrite;
       
  1646 	InitialiseForThread(task);
       
  1647 	free=FreeDiskSpace(KDefaultDrive);
       
  1648 	threshold1=free-400;
       
  1649 	TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
       
  1650 	session2.NotifyChange(ENotifyAll,stat2);
       
  1651 	session3.NotifyChange(ENotifyAll,stat3,KTestFile1);
       
  1652 	test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
       
  1653 	r=thread.Create(_L("thread2"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
       
  1654 	test(r==KErrNone);
       
  1655 	thread.Logon( deathStat );
       
  1656 	thread.Resume();
       
  1657 	User::After(1000000);
       
  1658 	User::WaitForRequest(stat1);
       
  1659 	User::WaitForRequest(stat2);
       
  1660 	User::WaitForRequest(stat3);
       
  1661 	test(stat1==KErrNone && stat2==KErrNone && stat3==KErrNone);
       
  1662 	free=FreeDiskSpace(KDefaultDrive);
       
  1663 	test(free<threshold1);
       
  1664 	User::WaitForRequest( deathStat );
       
  1665 	thread.Close();
       
  1666 	CleanupForThread(task);
       
  1667 
       
  1668 	// check cancellation of change notification and disk space notification
       
  1669 	// on same session
       
  1670 	test.Next(_L("test cancellation of notifications"));
       
  1671 	TheFs.NotifyDiskSpace(FreeDiskSpace(KDefaultDrive)-512,KDefaultDrive,stat1);
       
  1672 	TheFs.NotifyChange(ENotifyAll,stat2);
       
  1673 	TheFs.NotifyChange(ENotifyAll,stat3,KTestFile1);
       
  1674 	test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
       
  1675 	TheFs.NotifyChangeCancel();
       
  1676 	test(stat1==KRequestPending&&stat2==KErrCancel&&stat3==KErrCancel);
       
  1677 	TheFs.NotifyDiskSpaceCancel();
       
  1678 	test(stat1==KErrCancel);
       
  1679 	// request change notification again
       
  1680 	TheFs.NotifyDiskSpace(FreeDiskSpace(KDefaultDrive)-512,KDefaultDrive,stat1);
       
  1681 	TheFs.NotifyChange(ENotifyAll,stat2);
       
  1682 	TheFs.NotifyChange(ENotifyAll,stat3,KTestFile1);
       
  1683 	test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
       
  1684 	TheFs.NotifyDiskSpaceCancel();
       
  1685 	test(stat1==KErrCancel&&stat2==KRequestPending&&stat3==KRequestPending);
       
  1686 	TheFs.NotifyChangeCancel();
       
  1687 	test(stat1==KErrCancel&&stat2==KErrCancel&&stat3==KErrCancel);
       
  1688 
       
  1689 
       
  1690 	session2.Close();
       
  1691 	session3.Close();
       
  1692 
       
  1693 	file.Close();
       
  1694 	r=TheFs.Delete(KFileFiller);
       
  1695 	test(r==KErrNone);
       
  1696 
       
  1697 	}
       
  1698 
       
  1699 GLDEF_C void CallTestsL()
       
  1700 //
       
  1701 // Do all tests
       
  1702 //
       
  1703 	{
       
  1704 	TInt r = KErrNone;
       
  1705 	TInt driveNumber;
       
  1706 	if(IsTestingLFFS())
       
  1707 		{
       
  1708 		LffsDrive = ETrue;
       
  1709 		r = TheFs.CharToDrive( gSessionPath[0], driveNumber );
       
  1710 		test( KErrNone == r );
       
  1711 		}
       
  1712 
       
  1713 	// at present internal ram drive not tested - the test should allow for fact
       
  1714 	// that memory allocation will affect the free disk space on the internal ram drive
       
  1715 
       
  1716 	// pc file system c drive is also not tested - the test should allow for the fact
       
  1717 	// that other windows processes may affect the free disk space
       
  1718 #ifdef __WINS__
       
  1719 	if(gSessionPath[0]==(TText)'C')
       
  1720 #else
       
  1721 	// check if gSessionPath drive is RAM drive
       
  1722 	TDriveInfo driveInfo;
       
  1723 	test(KErrNone == TheFs.CharToDrive(gSessionPath[0], driveNumber));
       
  1724 	test(KErrNone == TheFs.Drive(driveInfo, driveNumber));
       
  1725 	if(driveInfo.iType == EMediaRam)
       
  1726 #endif
       
  1727 		{
       
  1728 #ifdef __WINS__
       
  1729 		test.Printf( _L("C:\\ is not tested, test will exit") );
       
  1730 #else
       
  1731 		test.Printf( _L("%c:\\ is not tested (is RAM drive), test will exit"), gSessionPath[0]);
       
  1732 #endif
       
  1733 		return;
       
  1734 		}
       
  1735 	//Test uses C drive as secondary drive so test can't be tested on that drive
       
  1736 	r = TheFs.CharToDrive(gSessionPath[0], driveNumber);
       
  1737 	test(r == KErrNone);
       
  1738 	if(driveNumber == EDriveC)
       
  1739 		{
       
  1740 		test.Printf(_L("Test uses C drive as secondary drive so test can't be test on C drive, test will exit"));
       
  1741 		return;
       
  1742 		}
       
  1743 
       
  1744 	Initialise();
       
  1745 	TestErrorConditions();
       
  1746 	TestCancellation();
       
  1747 	TestFunctions();
       
  1748 	TestMultiple();
       
  1749 	if( !LffsDrive )
       
  1750 		{
       
  1751 		TestDiskNotify();
       
  1752 		}
       
  1753 
       
  1754 	TestChangeNotification();
       
  1755 
       
  1756 	if( LffsDrive )
       
  1757 		{
       
  1758 
       
  1759 		TestLffsFunctions();
       
  1760 		TestLffsMultiple();
       
  1761 		}
       
  1762 	}
       
  1763