diff -r 000000000000 -r bde4ae8d615e os/kernelhwsrv/kerneltest/f32test/filesystem/fat/t_checkdisk.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/kernelhwsrv/kerneltest/f32test/filesystem/fat/t_checkdisk.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,677 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// f32test\server\t_CHECKDISK.cpp +// +// +#define __E32TEST_EXTENSION__ +#include +#include +//#include +//#include +#include "t_server.h" +//#include + +RTest test(_L("T_CHECKDISK")); + +RFs TheFs; +TInt gDrive; +TFileName gSessionPath; +TChar gDriveToTest; + + +HBufC8* gBuf = NULL; +TPtr8 gBufReadPtr(NULL, 0); +HBufC8* gBufSec = NULL; +TPtr8 gBufWritePtr(NULL, 0); + +const TInt KOneK = 1024; +const TInt KOneMeg = KOneK * 1024; +const TInt KBlockSize = KOneK * 129 ; +const TInt KWaitRequestsTableSize = 70; + +TInt gBigFileSize = 0; +TInt gSmallFileSize = 0; +TInt64 gMediaSize = 0; +TBool gSkip=EFalse; +TInt writeSize = KBlockSize; +TInt seekSize = 0; +TSeek seekType = ESeekAddress; +TInt reduceSize = 0; + +TTimeIntervalMicroSeconds32 gTimeTakenBigFile(0); +TBuf16<45> gSmallFile, gBigFile; +LOCAL_D TInt gNextFile=0; +TTime gTime1; +TTime gTime2; + +LOCAL_D RSemaphore gSync; + +// Concurrent Threads +RThread gBig; +RThread gSmall; +LOCAL_D RSemaphore client; +LOCAL_D const TInt KHeapSize=0x4000; +LOCAL_D const TInt KMaxHeapSize=0x100000; +TRequestStatus gStatus[KWaitRequestsTableSize]; + +enum TTestState + { + EThreadWait, + EThreadSignal, + ENoThreads + }; + +// +// Generates a name of the form FFFFF*.TXT (aLong.3) +// +GLDEF_C void FileNameGen(TDes16& aBuffer, TInt aLong, TInt aPos) + { + TInt padding; + TInt i=0; + TBuf16<10> tempbuf; + + _LIT(KNumber,"%d"); + tempbuf.Format(KNumber,aPos); + padding=aLong-tempbuf.Size()/2; + aBuffer=_L(""); + while(i cmd; + User::CommandLine(cmd); + TLex lex(cmd); + TPtrC token=lex.NextToken(); + TInt r=0; + + if(token.Length()!=0) + { + gDriveToTest=token[0]; + gDriveToTest.UpperCase(); + } + else + { + gDriveToTest='C'; + } + + r=TheFs.CharToDrive(gDriveToTest,gDrive); + test_KErrNone(r); + gSessionPath=_L("?:\\F32-TST\\"); + gSessionPath[0]=(TText)gDriveToTest; + test.Printf(_L("\nCLP=%S\n"),&token); + } + +// +// Fills a buffer with character aC +// +LOCAL_C void FillBuffer(TDes8& aBuffer, TInt aLength, TChar aC) + { + test (aBuffer.MaxLength() >= aLength); + for(TInt i=0; i0); // Block size must be greater than 0 + + if(aState==EThreadWait) + { + gSync.Wait(); + } + r=fileWrite.Replace(fs,aFile,EFileShareAny|EFileWrite); + test_KErrNone(r); + + TInt j=0; + while(j= 0) + writeSize += reduceSize; + + writeSize = Min(writeSize, gBufWritePtr.Length()); + + } + if((j==0)&&(aState==EThreadSignal)) + { + gSync.Signal(); + } + j+=aBlockSize; + } + + fileWrite.Close(); + + return KErrNone; + } + +LOCAL_C void IniStatus(TRequestStatus aStatus[], TInt aSize) + { + TInt i=0; + + while(i0); // Block size must be greater than 0 + test((aSize%aBlockSize)==0); // Ensure the size of the file is a multiple of the block size + + r=aFileWrite.Replace(fs,aFile,EFileShareAny|EFileWrite); + test_KErrNone(r); + + TInt j=0,i=0; + while(j unit=_L("?:\\"); + unit[0]=(TText)gDriveToTest; + + //------------------------------------------- + test.Printf(_L("Sync test\n")); + + r=gBig.Create(_L("TEST1"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL); + test_KErrNone(r); + + gBig.Resume(); + gSync.Wait(); + + gBig.Kill(-2); + gBig.Close(); + User::After(500000); + + r=TheFs.CheckDisk(unit); + test_Value(r, r == KErrNone || r == KErrNotSupported); + + //------------------------------------------- + test.Printf(_L("Async test\n")); + r=gSmall.Create(_L("TEST2"),WriteBigFileAsync,KDefaultStackSize*2,KHeapSize,KMaxHeapSize,NULL); + test_KErrNone(r); + + gSmall.Resume(); + gSync.Wait(); + + gSmall.Kill(-2); + gSmall.Close(); + User::After(500000); + + r=TheFs.CheckDisk(unit); + test_Value(r, r == KErrNone || r == KErrNotSupported); + + //------------------------------------------- + test.Printf(_L("Testing for size not multiple of blocksize\n")); + + writeSize = 5000; + r=gBig.Create(_L("TEST3"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL); + test_KErrNone(r); + gBig.Resume(); + gSync.Wait(); + + gBig.Kill(-2); + gBig.Close(); + User::After(500000); + + r=TheFs.CheckDisk(unit); + test_Value(r, r == KErrNone || r == KErrNotSupported); + + //------------------------------------------- + test.Printf(_L("Testing with seek current and write inside the file boundary\n")); + + writeSize = 5000; + seekType = ESeekCurrent; + seekSize = -5000; + reduceSize = -3000; + r=gBig.Create(_L("TEST4"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL); + test_KErrNone(r); + gBig.Resume(); + gSync.Wait(); + + gBig.Kill(-2); + gBig.Close(); + User::After(500000); + + r=TheFs.CheckDisk(unit); + test_Value(r, r == KErrNone || r == KErrNotSupported); + + //------------------------------------------- + test.Printf(_L("Testing with seek current and overwrite entire file\n")); + writeSize = 5000; + seekType = ESeekCurrent; + seekSize = -5000; + reduceSize = 0; + r=gBig.Create(_L("TEST5"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL); + test_KErrNone(r); + gBig.Resume(); + gSync.Wait(); + + gBig.Kill(-2); + gBig.Close(); + User::After(500000); + + r=TheFs.CheckDisk(unit); + test_Value(r, r == KErrNone || r == KErrNotSupported); + + //------------------------------------------- + test.Printf(_L("Testing with seek current and write outside the file boundary\n")); + + writeSize = 5000; + seekType = ESeekCurrent; + seekSize = -5000; + reduceSize = 5000; + r=gBig.Create(_L("TEST6"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL); + test_KErrNone(r); + gBig.Resume(); + gSync.Wait(); + + gBig.Kill(-2); + gBig.Close(); + User::After(500000); + + r=TheFs.CheckDisk(unit); + test_Value(r, r == KErrNone || r == KErrNotSupported); + + //------------------------------------------- + test.Printf(_L("Testing with seek current and write within the file boundary\n")); + writeSize = 5000; + seekType = ESeekCurrent; + seekSize = -3000; + reduceSize = -4000; + r=gBig.Create(_L("TEST7"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL); + test_KErrNone(r); + gBig.Resume(); + gSync.Wait(); + + gBig.Kill(-2); + gBig.Close(); + User::After(500000); + + r=TheFs.CheckDisk(unit); + test_Value(r, r == KErrNone || r == KErrNotSupported); + + //------------------------------------------- + test.Printf(_L("Testing with seek current and write exactly to file size\n")); + writeSize = 5000; + seekType = ESeekCurrent; + seekSize = -3000; + reduceSize = -3000; + r=gBig.Create(_L("TEST8"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL); + test_KErrNone(r); + gBig.Resume(); + gSync.Wait(); + + gBig.Kill(-2); + gBig.Close(); + User::After(500000); + + r=TheFs.CheckDisk(unit); + test_Value(r, r == KErrNone || r == KErrNotSupported); + + //------------------------------------------- + test.Printf(_L("Testing with seek current and write greater than file size\n")); + writeSize = 5000; + seekType = ESeekCurrent; + seekSize = -3000; + reduceSize = 10000; + r=gBig.Create(_L("TEST9"),WriteBigFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL); + test_KErrNone(r); + gBig.Resume(); + gSync.Wait(); + + gBig.Kill(-2); + gBig.Close(); + User::After(500000); + + r=TheFs.CheckDisk(unit); + test_Value(r, r == KErrNone || r == KErrNotSupported); + + TInt retries = 0; + + do + { + r=TheFs.ScanDrive(unit); + if (r != KErrNone) + test.Printf(_L("ScanDrive() returned %d\n"), r); + if (r == KErrInUse) + User::After(500000); + } + while (r == KErrInUse && ++retries < 5); + + test_Value(r, r == KErrNone || r == KErrNotSupported); + + } + + +//--------------------------------------------------------------------- +/** + Test that CheckDisk will not cause stack overflow on very deep directory structure. +*/ +void TestCheckDisk_VeryDeepDirectory() + { + test.Next(_L("Testing deep dir structure check")); + + TInt nRes; + TBuf<20> unit=_L("?:\\"); + unit[0]=(TText)gDriveToTest; + + //-- 1. create deep dir structure, like \\0\\1\\2\\...... 90 levels deep + const TInt KMaxDirDepth = 90; + + test.Printf(_L("Creating directory with %d subdirs.\n"),KMaxDirDepth); + + TFileName fn; + for(TInt i=0; i dir; + + test.Next(_L("Preparing the environmnet\n")); + + FileNameGen(gSmallFile, 8, gNextFile++); + FileNameGen(gBigFile, 8, gNextFile++); + dir=gSessionPath; + dir.Append(gSmallFile); + gSmallFile=dir; + dir=gSessionPath; + dir.Append(gBigFile); + gBigFile=dir; + + TRAPD(res,gBuf = HBufC8::NewL(KBlockSize+1)); + test(res == KErrNone && gBuf != NULL); + + gBufWritePtr.Set(gBuf->Des()); + FillBuffer(gBufWritePtr, KBlockSize, 'B'); + + TRAPD(res2,gBufSec = HBufC8::NewL(KBlockSize+1)); + test(res2 == KErrNone && gBufSec != NULL); + gBufReadPtr.Set(gBufSec->Des()); + + //--------------------------- + + TestClientDies(); + TestCheckDisk_VeryDeepDirectory(); + + delete gBuf; + delete gBufSec; + } + +LOCAL_C void DoTests() + { + TInt r=0; + + r=client.CreateLocal(0); + test_KErrNone(r); + + r=gSync.CreateLocal(0); + test_KErrNone(r); + + r=TheFs.SetSessionPath(gSessionPath); + test_KErrNone(r); + + r=TheFs.MkDirAll(gSessionPath); + test_Value(r, r == KErrNone || r == KErrAlreadyExists); + + TheFs.ResourceCountMarkStart(); + TRAP(r,CallTestsL()); + test_KErrNone(r); + TheFs.ResourceCountMarkEnd(); + } + +TBool CheckForDiskSize() + { + TVolumeInfo volInfo; + TInt r = TheFs.Volume(volInfo, gDrive); + test_KErrNone(r); + + gMediaSize = volInfo.iSize; + gSmallFileSize = KBlockSize; + gBigFileSize = KBlockSize*20; + while(((2*gBigFileSize)+KOneMeg) > gMediaSize ) + { + gBigFileSize -= (2*KBlockSize); + } + + if(gBigFileSize< (3*gSmallFileSize)) + return EFalse; + else + return ETrue; + } + +void Format(TInt aDrive) + { + + test.Next(_L("Format")); + TBuf<4> driveBuf=_L("?:\\"); + driveBuf[0]=(TText)(aDrive+'A'); + RFormat format; + TInt count; + TInt r=format.Open(TheFs,driveBuf,EQuickFormat,count); + test_KErrNone(r); + + while(count) + { + TInt r=format.Next(count); + test_KErrNone(r); + } + format.Close(); + } + + +static TBool IsFAT(RFs &aFsSession, TInt aDrive) +{ + _LIT(KFatName, "Fat"); + + TFileName f; + TInt r = aFsSession.FileSystemName(f, aDrive); + test_Value(r, r == KErrNone || r == KErrNotFound); + return (f.CompareF(KFatName) == 0); +} + + +GLDEF_C TInt E32Main() + { + + CTrapCleanup* cleanup; + cleanup=CTrapCleanup::New(); + + __UHEAP_MARK; + test.Title(); + test.Start(_L("Starting tests...")); + parseCommandLine(); + + TInt r = TheFs.Connect(); + test_KErrNone(r); + + TDriveInfo info; + TVolumeInfo volInfo; + r=TheFs.Drive(info,gDrive); + test_KErrNone(r); + + if(info.iMediaAtt&KMediaAttVariableSize) + {// Not testing in RAM Drives + test.Printf(_L("Tests skipped in RAM drive\n")); + goto out; + } + + r = TheFs.Volume(volInfo, gDrive); + if (r == KErrNotReady) + { + if (info.iType == EMediaNotPresent) + test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)gDriveToTest); + else + test.Printf(_L("%c: medium found (type %d) but drive not ready\nPrevious test may have hung; else, check hardware.\n"), (TUint)gDriveToTest, (TInt)info.iType); + } + else if (r == KErrCorrupt) + { + test.Printf(_L("%c: Media corruption; previous test may have aborted; else, check hardware\n"), (TUint)gDriveToTest); + } + test_KErrNone(r); + + if(!IsFAT(TheFs, gDrive)) + { + test.Printf(_L("Tests skipped on non-FAT drive\n")); + goto out; + } + + if ((volInfo.iDrive.iMediaAtt & KMediaAttFormattable)) + Format(gDrive); + + if(CheckForDiskSize()) + { + DoTests(); + if ((volInfo.iDrive.iMediaAtt & KMediaAttFormattable)) + Format(gDrive); + } + else + { + test.Printf(_L("Skipping tests due to lack of space to perform them in this unit\n")); + } +out: + test.End(); + + TheFs.Close(); + test.Close(); + + __UHEAP_MARKEND; + delete cleanup; + return(KErrNone); + }