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