kerneltest/f32test/concur/t_cfssoakfn.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2002-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_csfsoakfn.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <f32file.h>
       
    19 #include <e32test.h>
       
    20 #include <e32math.h>
       
    21 #include <f32dbg.h>
       
    22 #include "t_server.h"
       
    23 #include "t_tdebug.h"
       
    24 #include "t_cfssoak.h"
       
    25 
       
    26 /// Time value constants
       
    27 LOCAL_D const TInt KSecond   = 1000000;
       
    28 LOCAL_D const TInt KTenthSec = KSecond / 10;
       
    29 
       
    30 /// Time to wait before session/subsession close, to allow some writes to
       
    31 /// complete but not all (1 second per write with slow FS)
       
    32 LOCAL_D const TInt KSessionWaitTime = 25 * KTenthSec;
       
    33 
       
    34 /// Number of writes we expect to have completed
       
    35 LOCAL_D const TInt KSessionNumEnded = KSessionWaitTime / KSecond;
       
    36 
       
    37 GLREF_D TExtension gPrimaryExtensions[];
       
    38 // -----------------------------------------------------------------
       
    39 
       
    40 void TSoakStats::Print()
       
    41 ///
       
    42 /// Print a statistics header.
       
    43 ///
       
    44 	{
       
    45 	TTest::Printf(_L("                    Total                Fail\n"));
       
    46 	}
       
    47 
       
    48 void TSoakStats::Print(const TDesC& aTitle)
       
    49 ///
       
    50 /// Print the statistics for this item (title, total executed, number executed
       
    51 /// this time, total failures, failures this time) then reset the "this time"
       
    52 /// values.
       
    53 ///
       
    54 	{
       
    55 	TTest::Printf(_L("  %-8S %8d %+8d   %8d %+8d\n"),
       
    56 				  &aTitle, iTotal, iThis, iFail, iThisF);
       
    57 	iThis = 0;
       
    58 	iThisF = 0;
       
    59 	}
       
    60 
       
    61 void TSoakStats::Inc()
       
    62 ///
       
    63 /// Increment both the total and "this time" execution numbers.
       
    64 ///
       
    65 	{
       
    66 	iTotal++;
       
    67 	iThis++;
       
    68 	}
       
    69 
       
    70 void TSoakStats::Fail()
       
    71 ///
       
    72 /// Increment both the total and "this time" failure numbers.
       
    73 ///
       
    74 	{
       
    75 	iFail++;
       
    76 	iThisF++;
       
    77 	}
       
    78 
       
    79 
       
    80 // -----------------------------------------------------------------
       
    81 
       
    82 TSoakReadOnly::TSoakReadOnly() : iDrive(-1)
       
    83 ///
       
    84 /// Initialise the "read only" tests, connect the file session.
       
    85 ///
       
    86 	{
       
    87 	TInt r = iFs.Connect();
       
    88 	if (r != KErrNone)
       
    89 		TTest::Fail(HERE, r, _L("iFs connect"));
       
    90 	}
       
    91 
       
    92 TSoakReadOnly::TSoakReadOnly(TInt aDriveCh) : iDrive(aDriveCh)
       
    93 ///
       
    94 /// Initialise the "read only" tests, connect the file session, setting up
       
    95 /// a drive to be excluded from the reading.
       
    96 /// @param aDriveCh Drive letter to be excluded.
       
    97 ///
       
    98 	{
       
    99 	TInt r = iFs.Connect();
       
   100 	if (r != KErrNone)
       
   101 		TTest::Fail(HERE, r, _L("iFs connect"));
       
   102 	}
       
   103 
       
   104 TSoakReadOnly::~TSoakReadOnly()
       
   105 ///
       
   106 /// Destructor -- close the file session.
       
   107 ///
       
   108 	{
       
   109 	iFs.Close();
       
   110 	}
       
   111 
       
   112 TInt TSoakReadOnly::ReadFile(const TDesC& aName, TInt aSize)
       
   113 ///
       
   114 /// Read a file, expecting a certain size.  No check is done on the actual
       
   115 /// data, just that it can be read.
       
   116 /// @param aName Name of the file.
       
   117 /// @param aSize Expected file size.
       
   118 ///
       
   119 	{
       
   120 	TInt r = KErrNone;
       
   121 	RFile f;
       
   122 	iReads.Inc();
       
   123 	r = f.Open(iFs, aName, EFileStreamText);
       
   124 	if (r == KErrNotFound || r == KErrPathNotFound)
       
   125 		return KErrNone;
       
   126 	TBuf<256> errbuf;
       
   127 	if (r != KErrNone)
       
   128 		{
       
   129 		if (r != KErrInUse)
       
   130 			{
       
   131 			iFiles.Fail();
       
   132 			TTest::Printf(_L("%S -- open failed %S\n"), &aName, &TTest::ErrStr(r, errbuf));
       
   133 			}
       
   134 		else
       
   135 			TTest::Printf(_L("Warning: %S -- open failed %S\n"), &aName, &TTest::ErrStr(r, errbuf));
       
   136 		return r;
       
   137 		}
       
   138 	TBuf8<256> buf;
       
   139 	TInt len = 0;
       
   140 	while ((r = f.Read(buf)) == KErrNone && buf.Length() > 0)
       
   141 		len += buf.Length();
       
   142 	f.Close();
       
   143 	if (r != KErrNone && r != KErrEof)
       
   144 		{
       
   145 		iReads.Fail();
       
   146 		TTest::Printf(_L("ERROR %S -- READ FAILED %S\n"), &aName, &TTest::ErrStr(r, errbuf));
       
   147 		}
       
   148 	else if (len < aSize)
       
   149 		{
       
   150 		iReads.Fail();
       
   151 		TTest::Printf(_L("ERROR %S -- %d READ, %d EXPECTED\n"), &aName, len, aSize);
       
   152 		}
       
   153 	else if (len > aSize)
       
   154 		TTest::Printf(_L("Warning: %S -- %d read, %d expected\n"), &aName, len, aSize);
       
   155 	return r;
       
   156 	}
       
   157 
       
   158 TInt TSoakReadOnly::ScanDirs(TInt aDriveCh, TInt aReadInterval)
       
   159 ///
       
   160 /// Scan directories on a drive, reading a selection of the files found.
       
   161 /// @param aDriveCh Drive letter to be scanned.
       
   162 /// @param aReadInterval Approximate number of files to be read (they are
       
   163 ///                      read at random, so the actual number read may be
       
   164 ///                      less than this number).
       
   165 ///
       
   166 	{
       
   167 	TInt r = KErrNone;
       
   168 	CDirScan* scanner=NULL;
       
   169 	TRAP(r, scanner=CDirScan::NewL(iFs));
       
   170 	ScanDirFunc(scanner, aDriveCh, aReadInterval);
       
   171 	delete scanner;
       
   172 	return r;
       
   173 	}
       
   174 
       
   175 TInt TSoakReadOnly::ScanDirFunc(CDirScan* aScanner, TInt aDriveCh, TInt aReadInterval)
       
   176 ///
       
   177 /// Scan directories on a drive, reading a selection of the files found.
       
   178 /// @param aDriveCh Drive letter to be scanned.
       
   179 /// @param aReadInterval Approximate number of files to be read (they are
       
   180 ///                      read at random, so the actual number read may be
       
   181 ///                      less than this number).
       
   182 ///
       
   183 	{
       
   184 	TInt r = KErrNone;
       
   185 	TBuf<8> name;
       
   186 	name.Format(_L("%c:\\"), aDriveCh);
       
   187 	// TTest::Printf(_L("Scanning %S\n"), &name);
       
   188 	TParse dirName;
       
   189 	r=iFs.Parse(name, dirName);
       
   190 	if (r != KErrNone)
       
   191 		{
       
   192 		iDrives.Fail();
       
   193 		return r;
       
   194 		}
       
   195 	CDir* entryList = NULL;
       
   196 	TInt nfiles = 0;
       
   197 	TRAP(r, aScanner->SetScanDataL(dirName.FullName(),KEntryAttDir,ESortByName));
       
   198 	if (r != KErrNone)
       
   199 		{
       
   200 		TTest::Fail(HERE, r, _L("SetScanData %S"), &dirName.FullName());
       
   201 		}
       
   202 	TRAP(r, aScanner->NextL(entryList));
       
   203 	if (r == KErrPathNotFound)
       
   204 		return KErrNone;
       
   205 	if (r != KErrNone)
       
   206 		{
       
   207 		TTest::Fail(HERE, r, _L("Scan Next %S"), &dirName.FullName());
       
   208 		}
       
   209 	while (entryList)
       
   210 		{
       
   211 		for (TInt i = 0; i < entryList->Count(); i++)
       
   212 			{
       
   213 			TEntry e = (*entryList)[i];
       
   214 			if (!e.IsDir())
       
   215 				++nfiles;
       
   216 			}
       
   217 		delete entryList;
       
   218 		TRAP(r, aScanner->NextL(entryList));
       
   219 		if (r == KErrPathNotFound)
       
   220 			break;
       
   221 		if (r != KErrNone)
       
   222 			{
       
   223 			TTest::Fail(HERE, r, _L("Scan Next %S"), &dirName.FullName());
       
   224 			}
       
   225 		}
       
   226 	TInt prob = (nfiles / aReadInterval) + 1;
       
   227 	TRAP(r, aScanner->SetScanDataL(dirName.FullName(),KEntryAttDir,ESortByName));
       
   228 	if (r == KErrPathNotFound)
       
   229 		return KErrNone;
       
   230 	if (r != KErrNone)
       
   231 		{
       
   232 		TTest::Fail(HERE, r, _L("Scan Next %S"), &dirName.FullName());
       
   233 		}
       
   234 	for (;;)
       
   235 		{
       
   236 		TRAP(r, aScanner->NextL(entryList));
       
   237 		if (r == KErrPathNotFound)
       
   238 			return KErrNone;
       
   239 		if (r != KErrNone)
       
   240 			{
       
   241 			TTest::Fail(HERE, r, _L("Scan Next %S"), &dirName.FullName());
       
   242 			}
       
   243 		if (entryList==NULL)
       
   244 			break;
       
   245 		TInt count=entryList->Count();
       
   246 		while (count--)
       
   247 			{
       
   248 			TEntry e = (*entryList)[count];
       
   249 			TFileName path=aScanner->FullPath();
       
   250 			path.Append(e.iName);
       
   251 			TBuf<16> attr;
       
   252 			for (TInt j = 0; j < 16; j++)
       
   253 				{
       
   254 				if ((1 << j) & e.iAtt)
       
   255 					attr.Append(TText("RHSVDA X        "[j]));
       
   256 				}
       
   257 			if (e.IsDir())
       
   258 				{
       
   259 				iDirs.Inc();
       
   260 				// TTest::Printf(_L("%c:%-50S    <DIR>  %S\n"), aDriveCh, &path, &attr);
       
   261 				}
       
   262 			else
       
   263 				{
       
   264 				iFiles.Inc();
       
   265 				TBool read = (aReadInterval && Math::Rand(iSeed) % prob == 0);
       
   266 				if (read)
       
   267 					{
       
   268 					// TTest::Printf(_L("%-50S %8d  %-8S  test\n"), &path, e.iSize, &attr);
       
   269 					r = ReadFile(path, e.iSize);
       
   270 					}
       
   271 				else
       
   272 					{
       
   273 					// TTest::Printf(_L("%c:%-50S %8d  %S\n"), aDriveCh, &path, e.iSize, &attr);
       
   274 					}
       
   275 				}
       
   276 			}
       
   277 		delete entryList;
       
   278 		entryList=NULL;
       
   279 		}
       
   280 	return r;
       
   281 	}
       
   282 
       
   283 TInt TSoakReadOnly::ScanDrives(TBool aScanDirs, TInt aReadInterval)
       
   284 ///
       
   285 /// Scan all drives (except the one excluded) for directories and files.
       
   286 /// @param aScanDirs If true, read subdirectories, if false don't.
       
   287 /// @param aReadInterval approximate number of files to read.
       
   288 ///
       
   289 	{
       
   290 	TInt r = KErrNone;
       
   291 	TInt i;
       
   292 	for (i = EDriveA; i <= EDriveZ; i++)
       
   293 		{
       
   294 		TChar drv;
       
   295 		r=iFs.DriveToChar(i, drv);
       
   296 		if (r != KErrNone)
       
   297 			return r;
       
   298 		TDriveInfo info;
       
   299 		r=iFs.Drive(info, i);
       
   300 		if (r != KErrNone)
       
   301 			return r;
       
   302 		if (i != iDrive
       
   303 			&& info.iDriveAtt != 0
       
   304 			&& info.iType != EMediaUnknown
       
   305 			&& info.iType != EMediaNotPresent)
       
   306 			{
       
   307 			iDrives.Inc();
       
   308 			// TTest::Printf(_L("Drive %c:"), drv);
       
   309 			if (aScanDirs)
       
   310 				{
       
   311 				iDirs.Inc();
       
   312 				r = ScanDirs(drv, aReadInterval);
       
   313 				if (r != KErrNone)
       
   314 					return r;
       
   315 				}
       
   316 			}
       
   317 		}
       
   318 	return r;
       
   319 	}
       
   320 
       
   321 void
       
   322 TSoakReadOnly::ExcludeDrive(TInt aDriveCh)
       
   323 ///
       
   324 /// Set a drive to be excluded from scanning.
       
   325 /// @param aDriveCh Drive letter to be excluded.
       
   326 ///
       
   327 	{
       
   328 	iDrive = aDriveCh;
       
   329 	}
       
   330 
       
   331 
       
   332 // --------------------------------------------------------------------------
       
   333 
       
   334 TSoakFill::TSoakFill()
       
   335 ///
       
   336 /// Initialise the fill/clean cycle.
       
   337 ///
       
   338 	{
       
   339 	iSeed = 186483;
       
   340 	TInt r = iFs.Connect();
       
   341 	if (r != KErrNone)
       
   342 		TTest::Fail(HERE, r, _L("iFs connect"));
       
   343 	}
       
   344 
       
   345 TInt TSoakFill::SetDrive(TInt aDriveCh)
       
   346 ///
       
   347 /// Set a drive to be stressed.  The test directory is created and then it is
       
   348 /// cleaned (in case anything was left over from previous tests).  Note that
       
   349 /// other directories on the drive are untouched.
       
   350 /// @param aDriveCh Drive letter to be used.
       
   351 /// @leave The drive scanning can cause the function to leave.
       
   352 ///
       
   353 	{
       
   354 	TInt  r = KErrNone;
       
   355 	iDrive = aDriveCh;
       
   356 	if (aDriveCh)
       
   357 		{
       
   358 		iDrvCh = aDriveCh;
       
   359 		iFs.CharToDrive(iDrvCh, iDrive);
       
   360 		r=iFs.Volume(iInfo, iDrive);
       
   361 		if (r != KErrNone)
       
   362 			TTest::Fail(HERE, r, _L("volume info for %C:"), aDriveCh);
       
   363 		iFree = iInfo.iSize;
       
   364 		iName.Format(_L("%c:\\SOAK\\"), iDrvCh);
       
   365 		r = iFs.MkDir(iName);
       
   366 		if (r != KErrNone && r != KErrAlreadyExists)
       
   367 			TTest::Fail(HERE, r, _L("mkdir %S"), &iName);
       
   368 		r = KErrNone;
       
   369 		}
       
   370 	return r;
       
   371 	}
       
   372 
       
   373 TInt TSoakFill::FillDrive()
       
   374 ///
       
   375 /// Fill the drive with files and directories of random lengths.
       
   376 /// @param aDriveCh Drive letter to be tested, or zero (absent) to use the one
       
   377 ///        set up with SetDrive().
       
   378 /// @leave Setting up a new drive can cause this function to leave.
       
   379 ///
       
   380 	{
       
   381 	TInt  r = KErrNone;
       
   382 	r=iFs.Volume(iInfo, iDrive);
       
   383 	if (r != KErrNone)
       
   384 		TTest::Fail(HERE, r, _L("volume info for %C:"), iDrvCh);
       
   385 	iFree = iInfo.iFree;
       
   386 	r = iFs.MkDir(iName);
       
   387 	if (r != KErrNone && r != KErrAlreadyExists && r != KErrNotSupported)
       
   388 		TTest::Fail(HERE, r, _L("mkdir %S"), &iName);
       
   389 	do
       
   390 		{
       
   391 		r = Fill(iName);
       
   392 		if (r == KErrDiskFull)
       
   393 			{
       
   394 			// TTest::Printf(_L("Disk full on %c:\n"), iDrvCh);
       
   395 			break;
       
   396 			}
       
   397 		if (r != KErrNone)
       
   398 			TTest::Fail(HERE, r, _L("Filling drive %c"), iDrvCh);
       
   399 		r=iFs.Volume(iInfo, iDrive);
       
   400 		if (r != KErrNone)
       
   401 			TTest::Fail(HERE, r, _L("volume info for %c:"), iDrvCh);
       
   402 		} while (iInfo.iFree > 0);
       
   403 	r=iFs.Volume(iInfo, iDrive);
       
   404 	if (r != KErrNone)
       
   405 		TTest::Fail(HERE, r, _L("volume info for %c:"), iDrvCh);
       
   406 	if (iInfo.iFree > 0)
       
   407 		TTest::Printf(_L("Free space on %c: %S %ld KB (out of %ld KB)\n"),
       
   408 					  iDrvCh,
       
   409 					  &iInfo.iName,
       
   410 					  I64LOW(iInfo.iFree / 1024),
       
   411 					  I64LOW(iInfo.iSize / 1024));
       
   412 	return r;
       
   413 	}
       
   414 
       
   415 TInt TSoakFill::CleanDrive()
       
   416 ///
       
   417 /// Clean the test directory on the selected drive, removing all files and
       
   418 /// subdirectories.  Other directories on the drive are left untouched.
       
   419 /// @leave Scanning the drive can cause the function to leave.
       
   420 ///
       
   421 	{
       
   422 	TInt r = KErrNone;
       
   423 	CDirScan* scanner=0;
       
   424 	TRAP(r, scanner=CDirScan::NewL(iFs));
       
   425 	if (r != KErrNone || !scanner)
       
   426 		TTest::Fail(HERE, r, _L("creating scanner"));
       
   427 	TParse dirName;
       
   428 	r=iFs.Parse(iName, dirName);
       
   429 	if (r != KErrNone)
       
   430 		{
       
   431 		if (r == KErrInUse || r == KErrNotFound || r == KErrPathNotFound)
       
   432 			{
       
   433 			// valid conditions, don't report error
       
   434 			r = KErrNone;
       
   435 			}
       
   436 		else
       
   437 			TTest::Fail(HERE, r, _L("Parse %S"), &iName);
       
   438 		}
       
   439 	else
       
   440 		{
       
   441 		// TTest::Printf(_L("scan %S\n"), &iName);
       
   442 		CDir* entryList = NULL;
       
   443 		TRAP(r, scanner->SetScanDataL(dirName.FullName(),KEntryAttDir,ESortByName,CDirScan::EScanUpTree));
       
   444 		if (r != KErrNone)
       
   445 			TTest::Fail(HERE, r, _L("SetScanDataL(%S)"), &dirName.FullName());
       
   446 		TRAP(r, scanner->NextL(entryList));
       
   447 		if (r != KErrNone && r != KErrPathNotFound)
       
   448 			TTest::Fail(HERE, r, _L("Scan NextL()"));
       
   449 		while (entryList)
       
   450 			{
       
   451 			for (TInt i = 0; i < entryList->Count(); i++)
       
   452 				{
       
   453 				TEntry e = (*entryList)[i];
       
   454 				TFileName path = iName;
       
   455 				if (path.Right(1) == _L("\\"))
       
   456 					path.SetLength(path.Length()-1);
       
   457 				path.Append(scanner->AbbreviatedPath());
       
   458 				path.Append(e.iName);
       
   459 				// TTest::Printf(_L("remove %S\n"), &path);
       
   460 				TBuf<256> buf;
       
   461 				TInt maxInUseCount = 120;
       
   462 				do
       
   463 					{
       
   464 					if (e.IsDir())
       
   465 						{
       
   466 						if (path.Right(1) != _L("\\"))
       
   467 							path.Append(_L("\\"));
       
   468 						r = iFs.RmDir(path);
       
   469 						}
       
   470 					else
       
   471 						r = iFs.Delete(path);
       
   472 					if (r == KErrInUse)
       
   473 						{
       
   474 						TTest::Printf(_L("Warning: %S deleting %S\n"), &TTest::ErrStr(r, buf), &path);
       
   475 						User::After(1*KSecond);
       
   476 						}
       
   477 					}
       
   478 					while (r == KErrInUse && maxInUseCount-- > 0);
       
   479 				if (r != KErrNone)
       
   480 					{
       
   481 					TTest::Printf(_L("ERROR %S deleting %S\n"), &TTest::ErrStr(r, buf), &path);
       
   482 					}
       
   483 				}
       
   484 			delete entryList;
       
   485 			TRAP(r, scanner->NextL(entryList));
       
   486 			if (r != KErrNone)
       
   487 				TTest::Fail(HERE, r, _L("Scan NextL()"));
       
   488 			}
       
   489 		}
       
   490 	delete scanner;
       
   491 	r = iFs.RmDir(iName);
       
   492 	if (r != KErrNone && r != KErrNotFound && r != KErrPathNotFound)
       
   493 		{
       
   494 		TTest::Fail(HERE, r, _L("volume info for %C:"), iName[0]);
       
   495 		}
       
   496 	r=iFs.Volume(iInfo, iDrive);
       
   497 	if (r != KErrNone)
       
   498 		{
       
   499 		TTest::Fail(HERE, r, _L("volume info for %C:"), iName[0]);
       
   500 		}
       
   501 	if (iInfo.iFree > iFree)
       
   502 		{
       
   503 		TTest::Printf(_L("Warning: %C: changed size -- was %ld now %ld\n"),
       
   504 					  iName[0], iFree, iInfo.iFree);
       
   505 		return r;
       
   506 		}
       
   507 	iFree = iInfo.iFree;
       
   508 	return r;
       
   509 	}
       
   510 
       
   511 TInt TSoakFill::Fill(TFileName& aName, TInt aNfiles)
       
   512 ///
       
   513 /// Recursively create files and subdirectories at random.  If a subdirectory
       
   514 /// is created, the function recurses to fill it.  This generates a mixture of
       
   515 /// directories and files of varying lengths.
       
   516 /// @param aName   Directory in which to create other stuff.
       
   517 /// @param aNfiles Maximum number of files to create.
       
   518 /// @return Status of last thing created, KErrDiskFull when out of space.
       
   519 ///
       
   520 	{
       
   521 	TInt oldlen = aName.Length();
       
   522 	if (oldlen + 10 > aName.MaxLength())
       
   523 		return KErrNone;
       
   524 	TInt r=iFs.Volume(iInfo, iDrive);
       
   525 	if (r != KErrNone)
       
   526 		return r;
       
   527 	TInt nfiles = I64LOW(iInfo.iFree/10000) + 5;
       
   528 	if (aNfiles > 0 && nfiles > aNfiles)
       
   529 		nfiles = aNfiles;
       
   530 	nfiles = Math::Rand(iSeed) % nfiles + 5;
       
   531 	TInt filesz = I64LOW(iInfo.iFree/nfiles/256) + 5;
       
   532 	// TTest::Printf(_L("nfiles = %d\n"), nfiles);
       
   533 	TInt i;
       
   534 	for (i = 0; i < nfiles; i++)
       
   535 		{
       
   536 		aName.SetLength(oldlen);
       
   537 		TBool dir = (Math::Rand(iSeed) % 5 == 0);
       
   538 		if (dir && oldlen < 80)
       
   539 			{
       
   540 			aName.Append(_L("d"));
       
   541 			aName.AppendNum(i);
       
   542 			aName.Append(_L("\\"));
       
   543 			r = iFs.MkDir(aName);
       
   544 			TInt busycount = 120;
       
   545 			while (busycount-- > 0)
       
   546 				{
       
   547 				r = iFs.MkDir(aName);
       
   548 				if (r == KErrDiskFull)
       
   549 					TTest::Printf(_L("Disk full creating %S\n"), &aName);
       
   550 				if (r != KErrInUse)
       
   551 					break;
       
   552 				TTest::Printf(_L("Warning: KErrInUse creating %S\n"), &aName);
       
   553 				User::After(1*KSecond);
       
   554 				}
       
   555 			// TTest::Printf(_L("mkdir %S = %d\n"), &aName, r);
       
   556 			if (r == KErrNone || r == KErrAlreadyExists)
       
   557 				{
       
   558 				r = Fill(aName, nfiles - i - 2);
       
   559 				}
       
   560 			if (r != KErrNone)
       
   561 				break;
       
   562 			}
       
   563 		else
       
   564 			{
       
   565 			aName.Append(_L("F"));
       
   566 			aName.AppendNum(i);
       
   567 			RFile f;
       
   568 			TInt busycount = 120;
       
   569 			while (busycount-- > 0)
       
   570 				{
       
   571 				r = f.Replace(iFs, aName, EFileStreamText | EFileWrite);
       
   572 				if (r != KErrInUse)
       
   573 					break;
       
   574 				TTest::Printf(_L("Warning: KErrInUse creating %S\n"), &aName);
       
   575 				User::After(1*KSecond);
       
   576 				}
       
   577 			if (r == KErrNone)
       
   578 				{
       
   579 				// iNames.AppendL(aName);
       
   580 				TInt num = Math::Rand(iSeed) % filesz + 10;
       
   581 				TBuf8<256> buf;
       
   582 				buf.Fill(TText(' '), 256);
       
   583 				TInt wr = 0;
       
   584 				while (num-- > 0 && r == KErrNone)
       
   585 					{
       
   586 					r = f.Write(buf);
       
   587 					if (r == KErrNone)
       
   588 						wr += 256;
       
   589 					else
       
   590 						break;
       
   591 					}
       
   592 				f.Close();
       
   593 				/*
       
   594 				if (r == KErrDiskFull)
       
   595 					TTest::Printf(_L("Disk full writing %S\n"), &aName);
       
   596 				*/
       
   597 				if (r != KErrNone)
       
   598 					break;
       
   599 				}
       
   600 			else
       
   601 				{
       
   602 				// TTest::Printf(_L("creat %S = %d\n"), &aName, r);
       
   603 				if (r == KErrDiskFull)
       
   604 					TTest::Printf(_L("Disk full creating %S\n"), &aName);
       
   605 				break;
       
   606 				}
       
   607 			}
       
   608 		}
       
   609 	aName.SetLength(oldlen);
       
   610 	return r;
       
   611 	}
       
   612 
       
   613 
       
   614 TSoakRemote::TSoakRemote(TInt aDriveCh)
       
   615 ///
       
   616 /// Initialise testing for 'remote' drive (special filesystem).  Connects to
       
   617 /// file session, initialises the drive and timer, sets up the buffers and
       
   618 /// file name.
       
   619 /// @param aDriveCh Drive letter for the drive to test.
       
   620 ///
       
   621 	{
       
   622 	TInt r = iFs.Connect();
       
   623 	if (r != KErrNone)
       
   624 		TTest::Fail(HERE, r, _L("iFs connect"));
       
   625 	iDrvCh = aDriveCh;
       
   626 	iSync  = EFalse;
       
   627 	iFs.CharToDrive(iDrvCh, iDrive);
       
   628 	iTimer.CreateLocal();
       
   629 	Setup();
       
   630 	}
       
   631 
       
   632 void TSoakRemote::Setup()
       
   633 /// Set up the buffers and the filename to be used.
       
   634 	{
       
   635 	for (TInt i = 0; i < KSoakNumBuf; i++)
       
   636 		{
       
   637 		iBuff[i].Fill('_', KSoakBufLen);
       
   638 		iStat[i] = KErrNone;
       
   639 		}
       
   640 	iName.Format(_L("%c:\\SOAKTEST.FILE"), iDrvCh);
       
   641 	}
       
   642 
       
   643 void TSoakRemote::Remount(TBool aSync)
       
   644 ///
       
   645 /// Remount the test drive as (a)synchronous.
       
   646 /// @param aSync If true, the drive is set as synchronous access, otherwise
       
   647 ///              as asynchronous.
       
   648 ///
       
   649 	{
       
   650 	TFileName fsname;
       
   651 	iSync = aSync;
       
   652 	TInt r = iFs.FileSystemName(fsname, iDrive);
       
   653 	TEST(r == KErrNone || r == KErrNotFound);
       
   654 
       
   655 	if (fsname.Length() > 0)
       
   656 		{
       
   657 		r = iFs.ExtensionName(gPrimaryExtensions[iDrive].iName, iDrive, 0);
       
   658 		if (r == KErrNone)
       
   659 			gPrimaryExtensions[iDrive].iExists = ETrue;
       
   660 
       
   661 		r = iFs.DismountFileSystem(fsname, iDrive);
       
   662 		if(r != KErrNone)
       
   663 			{
       
   664 			TTest::Fail(HERE, r, _L("Dismounting file system %S"), &fsname);
       
   665 			}
       
   666 		}
       
   667 
       
   668 	TBufC<16> type = _L("asynchronous");
       
   669 	if (iSync)
       
   670 		type = _L("synchronous");
       
   671 	TTest::Printf(_L("Remount filesystem %c: %S as %S\n"), iDrvCh, &fsname, &type);
       
   672 
       
   673 #ifdef __CONCURRENT_FILE_ACCESS__
       
   674 	if (gPrimaryExtensions[iDrive].iExists == EFalse)
       
   675 		r=iFs.MountFileSystem(fsname,iDrive,iSync);
       
   676 	else
       
   677 		r=iFs.MountFileSystem(fsname,gPrimaryExtensions[iDrive].iName,iDrive,iSync);
       
   678 #else
       
   679 	if (gPrimaryExtensions[aDrive].iExists == EFalse)
       
   680 		r=iFs.MountFileSystem(fsname,iDrive);
       
   681 	else
       
   682 		r=iFs.MountFileSystem(fsname,gPrimaryExtensions[iDrive].iName,iDrive);
       
   683 #endif
       
   684 	TEST(r==KErrNone);
       
   685 	}
       
   686 
       
   687 TInt TSoakRemote::TestSubSession()
       
   688 ///
       
   689 /// Test what happens when a file is closed in the middle of writing it.  Note
       
   690 /// that this assumes that the filesystem under test takes a second for each
       
   691 /// write operation (i.e. is the special test filesystem).
       
   692 ///
       
   693 	{
       
   694 	TInt r = iFile.Replace(iFs, iName, EFileStreamText | EFileWrite);
       
   695 	if (r != KErrNone)
       
   696 		TTest::Fail(HERE, r, _L("opening %S for writing"), iName.Ptr());
       
   697 	TInt i;
       
   698 	for (i = 0; i < KSoakNumBuf; i++)
       
   699 		{
       
   700 		iFile.Write(iBuff[i], iStat[i]);
       
   701 		}
       
   702 	// wait for a couple of writes to complete, then close the file before the
       
   703 	// others finish
       
   704 	User::After(KSessionWaitTime);
       
   705 	TTest::Printf(_L("Wait ended"));
       
   706 	iFile.Close();
       
   707 	TTest::Printf(_L("Close ended"));
       
   708 	// test what has happened
       
   709 	TBool bad = EFalse;
       
   710 	for (i = 0; i < KSoakNumBuf; i++)
       
   711 		{
       
   712 		User::WaitForRequest(iStat[i]);
       
   713 		r = iStat[i].Int();
       
   714 		switch (r)
       
   715 			{
       
   716 			case KErrNone:
       
   717 				if (i >= KSessionNumEnded)
       
   718 					{
       
   719 					TTest::Printf(_L("Write %d not cancelled"), i);
       
   720 					bad = ETrue;
       
   721 					}
       
   722 				break;
       
   723 			case KErrCancel:
       
   724 				if (i <= KSessionNumEnded)
       
   725 					{
       
   726 					TTest::Printf(_L("Write %d incorrectly cancelled"), i);
       
   727 					bad = ETrue;
       
   728 					}
       
   729 				TTest::Printf(_L("write %d cancelled\n"), i);
       
   730 				break;
       
   731 			default:
       
   732 				TTest::Fail(HERE, r, _L("incorrect status for write %d"), i);
       
   733 			}
       
   734 		}
       
   735 	iFs.Delete(iName);
       
   736 	TPtrC sbuf(iSync ? _L("sync") : _L("async"));
       
   737 	if (bad)
       
   738 		{
       
   739 		TTest::Printf(_L("TestSubSession %c: %S FAILED\n"), iName[0], &sbuf);
       
   740 		// Commented out for the moment as result is undefined
       
   741 		// TTest::Fail(HERE, _L("TestSubSession %c: %S FAILED\n"), iName[0], &sbuf);
       
   742 		}
       
   743 	TTest::Printf(_L("TestSubSession %c: %S OK\n"), iName[0], &sbuf);
       
   744 	return KErrNone;
       
   745 	}
       
   746 
       
   747 TInt TSoakRemote::TestSession()
       
   748 ///
       
   749 /// Test what happens when a session is closed in the middle of writing a file.
       
   750 /// Note that this assumes that the filesystem under test takes a second for
       
   751 /// each write operation (i.e. is the special test filesystem).
       
   752 ///
       
   753 	{
       
   754 	TInt r;
       
   755 	TInt i;
       
   756 	TPtrC sbuf(iSync ? _L("sync") : _L("async"));
       
   757 
       
   758 	r = iFile.Replace(iFs, iName, EFileStreamText | EFileWrite);
       
   759 	if (r != KErrNone)
       
   760 		TTest::Fail(HERE, r, _L("opening %S for writing"), iName.Ptr());
       
   761 	for (i = 0; i < KSoakNumBuf; i++)
       
   762 		{
       
   763 		iFile.Write(iBuff[i], iStat[i]);
       
   764 		}
       
   765 	// wait for a couple of them to complete, then close the session
       
   766 	User::After(KSessionWaitTime);
       
   767 	TTest::Printf(_L("Close FS %S"), &sbuf);
       
   768 	// iFs.SetDebugRegister(KFSYS | KFSERV | KTHRD);
       
   769 	iFs.Close();
       
   770 	TTest::Printf(_L("FS closed %S"), &sbuf);
       
   771 	// see what has happened to the writes (wait for at most another 10 seconds).
       
   772 	TRequestStatus tstat;
       
   773 	iTimer.After(tstat, 10*KSecond);
       
   774 	TBool busy = ETrue;
       
   775 	TInt  file = 0;
       
   776 	while (tstat == KRequestPending && busy)
       
   777 		{
       
   778 		User::WaitForAnyRequest();
       
   779 		busy = EFalse;
       
   780 		for (i = file; i < KSoakNumBuf; i++)
       
   781 			{
       
   782 			r = iStat[i].Int();
       
   783 			switch (r)
       
   784 				{
       
   785 				case KRequestPending:
       
   786 					busy = ETrue;
       
   787 					TTest::Printf(_L("write %d pending\n"), i);
       
   788 					break;
       
   789 				case KErrNone:
       
   790 					file = i + 1;
       
   791 					TTest::Printf(_L("write %d finished\n"), i);
       
   792 					break;
       
   793 				case KErrCancel:
       
   794 					file = i + 1;
       
   795 					TTest::Printf(_L("write %d cancelled\n"), i);
       
   796 					break;
       
   797 				default:
       
   798 					file = i + 1;
       
   799 					TTest::Fail(HERE, r, _L("incorrect status for write %d"), i);
       
   800 				}
       
   801 			}
       
   802 		}
       
   803 	TBool bad = EFalse;
       
   804 	if (busy)
       
   805 		{
       
   806 		for (i = 0; i < KSoakNumBuf; i++)
       
   807 			{
       
   808 			TBuf<64> buf;
       
   809 			r = iStat[i].Int();
       
   810 			if (r != KErrNone)
       
   811 				{
       
   812 				// We expect that the third and subsequent requests will either
       
   813 				// have failed with cancel or be still outstanding.  If either
       
   814 				// of the first two have failed or are outstanding, that's an
       
   815 				// error.
       
   816 				if (i < KSessionNumEnded || (r != KErrCancel && r != KRequestPending))
       
   817 					{
       
   818 					TTest::Fail(HERE, _L("write %d: %S\n"), i, &TTest::ErrStr(r, buf));
       
   819 					bad = ETrue;
       
   820 					}
       
   821 				}
       
   822 			}
       
   823 		}
       
   824 	iTimer.Cancel();
       
   825 	// if it's got this far, re-connect the file session
       
   826 	// User::After(100000);
       
   827 	// TTest::Printf(_L("FS closed (%S) yet?"), &sbuf);
       
   828 	r = iFs.Connect();
       
   829 	iFs.SetDebugRegister(0);
       
   830 	// TTest::Printf(_L("FS opened"));
       
   831 	if (r != KErrNone)
       
   832 		TTest::Fail(HERE, r, _L("iFs connect"));
       
   833 	r = iFs.Delete(iName);
       
   834 	for (TInt nr = 0; r == KErrInUse && nr < 100; nr++)
       
   835 		{
       
   836 		TTest::Printf(_L("Wait for previous session to close"));
       
   837 		User::After(10*KSecond);
       
   838 		r = iFs.Delete(iName);
       
   839 		}
       
   840 	if (r == KErrNotFound)
       
   841 		r = KErrNone;
       
   842 	if (r != KErrNone)
       
   843 		bad = ETrue;
       
   844 	TPtrC obuf(bad ? _L("FAIL") : _L("OK"));
       
   845 	TTest::Printf(_L("TestSession %c: %S %S\n"), iName[0], &sbuf, &obuf);
       
   846 	if (bad)
       
   847 		{
       
   848 		TTest::Printf(_L("Test session close %c: %S FAILED\n"), iName[0], &sbuf);
       
   849 		// Commented out for the moment as result is undefined
       
   850 		// TTest::Fail(HERE, _L("Test session close failed"));
       
   851 		}
       
   852 	return r;
       
   853 	}
       
   854 
       
   855 TInt TSoakRemote::TestMount()
       
   856 ///
       
   857 /// Test dismounting with a file open (should fail)
       
   858 ///
       
   859 	{
       
   860 	TFileName fsname;
       
   861 	TInt r = iFs.FileSystemName(fsname, iDrive);
       
   862 	TEST(r == KErrNone || r == KErrNotFound);
       
   863 
       
   864 	TPtrC sbuf(iSync ? _L("sync") : _L("async"));
       
   865 
       
   866 	r = iFile.Replace(iFs, iName, EFileStreamText | EFileWrite);
       
   867 	for (TInt nr = 0; r == KErrInUse && nr < 100; nr++)
       
   868 		{
       
   869 		TTest::Printf(_L("Warning: KErrInUse opening %S for writing\n"), &iName);
       
   870 		User::After(10*KSecond);
       
   871 		r = iFile.Replace(iFs, iName, EFileStreamText | EFileWrite);
       
   872 		}
       
   873 	if (r != KErrNone)
       
   874 		TTest::Fail(HERE, r, _L("opening %S for writing"), &iName);
       
   875 
       
   876 	if (fsname.Length() > 0)
       
   877 		{
       
   878 		r = iFs.DismountFileSystem(fsname, iDrive);
       
   879 		if (r == KErrNone)
       
   880 			{
       
   881 #ifdef __CONCURRENT_FILE_ACCESS__
       
   882 			r = iFs.MountFileSystem(fsname, iDrive, iSync);
       
   883 #else
       
   884 			r = iFs.MountFileSystem(fsname, iDrive);
       
   885 #endif
       
   886 			if (r != KErrNone)
       
   887 				TTest::Fail(HERE, r, _L("MountFileSystem(%S, %C:)"), &fsname, iDrvCh);
       
   888 			}
       
   889 		else if (r != KErrInUse)
       
   890 			{
       
   891 			TTest::Fail(HERE, r, _L("DismountFileSystem(%S, %C:)"), &fsname, iDrvCh);
       
   892 			}
       
   893 		}
       
   894 
       
   895 	iFile.Close();
       
   896 	iFs.Delete(iName);
       
   897 
       
   898 	TTest::Printf(_L("TestMount %c: %S OK\n"), iName[0], &sbuf);
       
   899 
       
   900 	return KErrNone;
       
   901 	}
       
   902 
       
   903