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