sl@0: // Copyright (c) 1997-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_main.cpp sl@0: // sl@0: // sl@0: sl@0: #define __E32TEST_EXTENSION__ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "t_server.h" sl@0: sl@0: GLDEF_D RFs TheFs; sl@0: GLDEF_D TFileName gSessionPath; sl@0: GLDEF_D TInt gAllocFailOff=KAllocFailureOff; sl@0: GLDEF_D TInt gAllocFailOn=KAllocFailureOff; sl@0: GLDEF_D TInt64 gSeed=51703; sl@0: sl@0: GLDEF_D TChar gDriveToTest; sl@0: GLDEF_D TVolumeInfo gVolInfo; // volume info for current drive sl@0: GLDEF_D TFileCacheFlags gDriveCacheFlags; sl@0: sl@0: _LIT(KPrivate, "\\Private\\"); sl@0: sl@0: sl@0: //////////////////////////////////////////////////////////// sl@0: // Template functions encapsulating ControlIo magic sl@0: // sl@0: GLDEF_D template sl@0: GLDEF_C TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c) sl@0: { sl@0: TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C)); sl@0: sl@0: TInt r = fs.ControlIo(drv, fkn, ptrC); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: sl@0: GLDEF_C void CreateShortName(TDes& aFileName,TInt64& aSeed) sl@0: // sl@0: // Create a random, dos legal 8.3 char name sl@0: // sl@0: { sl@0: sl@0: TInt length=Math::Rand(aSeed)%11; sl@0: if (length==0) sl@0: length=1; sl@0: else if (length==3) // don't create three letter names like 'AUX' or 'PRN' sl@0: length++; sl@0: else if (length>8) // end in '.' if no extension sl@0: length++; sl@0: sl@0: aFileName.SetLength(length); sl@0: for(TInt i=0;i0) sl@0: length=aLength; sl@0: else sl@0: { sl@0: length=Math::Rand(aSeed)%128; sl@0: length+=Math::Rand(aSeed)%128; sl@0: length+=Math::Rand(aSeed)%128; sl@0: length+=Math::Rand(aSeed)%128; sl@0: length-=256; sl@0: length=Abs(length); sl@0: if (length==0) sl@0: length=1; sl@0: if (length>220) sl@0: length=31; sl@0: } sl@0: if (length==3) // don't create three letter names like 'AUX' or 'PRN' sl@0: length++; sl@0: sl@0: aFileName.SetLength(length); sl@0: TInt spaceChar=-1; sl@0: TInt i; sl@0: for(i=0;i': sl@0: case ':': sl@0: case '"': sl@0: case '/': sl@0: case '|': sl@0: case '*': sl@0: case '?': sl@0: case '\\': sl@0: case '\0': sl@0: break; sl@0: default: sl@0: illegalChar=EFalse; sl@0: }; sl@0: } sl@0: aFileName[i]=(TText)letter; sl@0: } sl@0: sl@0: if (spaceChar!=-1) sl@0: { sl@0: i=spaceChar; sl@0: goto StartAgain; sl@0: } sl@0: } sl@0: sl@0: sl@0: GLDEF_C void CheckDisk() sl@0: // sl@0: // Do a checkdisk and report failure sl@0: // sl@0: { sl@0: test.Next(_L("Check Disk")); sl@0: TInt r=TheFs.CheckDisk(gSessionPath); sl@0: if (r!=KErrNone && r!=KErrNotSupported && r!=KErrPermissionDenied) sl@0: ReportCheckDiskFailure(r); sl@0: } sl@0: sl@0: GLDEF_C void ReportCheckDiskFailure(TInt aRet) sl@0: // sl@0: // Report the failure of checkdisk sl@0: // sl@0: { sl@0: sl@0: test.Printf(_L("CHECKDISK FAILED: ")); sl@0: switch(aRet) sl@0: { sl@0: case 1: test.Printf(_L("File cluster chain contains a bad value (<2 or >maxCluster)\n")); break; sl@0: case 2: test.Printf(_L("Two files are linked to the same cluster\n")); break; sl@0: case 3: test.Printf(_L("Unallocated cluster contains a value != 0\n")); break; sl@0: case 4: test.Printf(_L("Size of file != number of clusters in chain\n")); break; sl@0: default: test.Printf(_L("Undefined Error value %d\n"),aRet); sl@0: } sl@0: test(EFalse); sl@0: } sl@0: sl@0: sl@0: GLDEF_C void MakeFile(const TDesC& aFileName,const TUidType& aUidType,const TDesC8& aFileContents) sl@0: // sl@0: // Make a file and write uid and data sl@0: // sl@0: { sl@0: sl@0: RFile file; sl@0: TInt r=file.Replace(TheFs,aFileName,0); sl@0: if (r==KErrPathNotFound) sl@0: { sl@0: r=TheFs.MkDirAll(aFileName); sl@0: test_KErrNone(r); sl@0: r=file.Replace(TheFs,aFileName,0); sl@0: } sl@0: test_KErrNone(r); sl@0: TCheckedUid checkedUid(aUidType); sl@0: TPtrC8 uidData((TUint8*)&checkedUid,sizeof(TCheckedUid)); sl@0: r=file.Write(uidData); sl@0: test_KErrNone(r); sl@0: r=file.Write(aFileContents); sl@0: test_KErrNone(r); sl@0: file.Close(); sl@0: } sl@0: sl@0: GLDEF_C void MakeFile(const TDesC& aFileName,const TDesC8& aFileContents) sl@0: // sl@0: // Make a file and write something in it sl@0: // sl@0: { sl@0: sl@0: RFile file; sl@0: TInt r=file.Replace(TheFs,aFileName,0); sl@0: if (r==KErrPathNotFound) sl@0: { sl@0: r=TheFs.MkDirAll(aFileName); sl@0: test_KErrNone(r); sl@0: r=file.Replace(TheFs,aFileName,0); sl@0: } sl@0: test_KErrNone(r); sl@0: r=file.Write(aFileContents); sl@0: test_KErrNone(r); sl@0: file.Close(); sl@0: } sl@0: sl@0: GLDEF_C void MakeFile(const TDesC& aFileName,TInt anAttributes) sl@0: // sl@0: // Make a file and write something in it sl@0: // sl@0: { sl@0: sl@0: RFile file; sl@0: TInt r=file.Replace(TheFs,aFileName,0); sl@0: if (r==KErrPathNotFound) sl@0: { sl@0: r=TheFs.MkDirAll(aFileName); sl@0: test_KErrNone(r); sl@0: r=file.Replace(TheFs,aFileName,0); sl@0: } sl@0: test_KErrNone(r); sl@0: file.Close(); sl@0: r=TheFs.SetAtt(aFileName,anAttributes,0); sl@0: test_KErrNone(r); sl@0: } sl@0: sl@0: GLDEF_C void MakeFile(const TDesC& aFileName) sl@0: // sl@0: // Make a file sl@0: // sl@0: { sl@0: sl@0: MakeFile(aFileName,_L8("")); sl@0: } sl@0: sl@0: GLDEF_C void MakeDir(const TDesC& aDirName) sl@0: // sl@0: // Make a directory sl@0: // sl@0: { sl@0: sl@0: TInt r=TheFs.MkDirAll(aDirName); sl@0: if (r!=KErrNone && r!=KErrAlreadyExists) sl@0: { sl@0: test.Printf(_L("%c: MakeDir Error %d\n"),aDirName[0],r); sl@0: test(0); sl@0: } sl@0: } sl@0: sl@0: sl@0: GLDEF_C void DeleteTestDirectory() sl@0: // sl@0: // Delete the leaf session path directory sl@0: // sl@0: { sl@0: sl@0: TheFs.SetAtt(_L("\\F32-TST\\SCANTEST\\Left\\Dir3\\Dir4\\Hidden"), 0, KEntryAttHidden); sl@0: TheFs.SetAtt(_L("\\F32-TST\\SCANTEST\\Left\\Dir3\\Dir4\\Hidden\\HiddenFile"), 0, KEntryAttHidden); sl@0: TheFs.SetAtt(_L("\\F32-TST\\SCANTEST\\Left\\Dir3\\Dir4\\Hidden\\System"), 0, KEntryAttSystem); sl@0: test.Next(_L("Delete test directory")); sl@0: CFileMan* fMan=CFileMan::NewL(TheFs); sl@0: test(fMan!=NULL); sl@0: TInt r=TheFs.SessionPath(gSessionPath); sl@0: test_KErrNone(r); sl@0: r=TheFs.CheckDisk(gSessionPath); sl@0: if (r!=KErrNone && r!=KErrNotSupported) sl@0: ReportCheckDiskFailure(r); sl@0: r=fMan->RmDir(gSessionPath); sl@0: test_KErrNone(r); sl@0: delete fMan; sl@0: } sl@0: sl@0: GLDEF_C void CreateTestDirectory(const TDesC& aSessionPath) sl@0: // sl@0: // Create directory for test sl@0: // sl@0: { sl@0: TParsePtrC path(aSessionPath); sl@0: test(path.DrivePresent()==EFalse); sl@0: sl@0: TInt r=TheFs.SetSessionPath(aSessionPath); sl@0: test_KErrNone(r); sl@0: r=TheFs.SessionPath(gSessionPath); sl@0: test_KErrNone(r); sl@0: r=TheFs.MkDirAll(gSessionPath); sl@0: test_Value(r, r == KErrNone || r == KErrAlreadyExists); sl@0: } sl@0: sl@0: GLDEF_C TInt CurrentDrive() sl@0: // sl@0: // Return the current drive number sl@0: // sl@0: { sl@0: sl@0: TInt driveNum; sl@0: TInt r=TheFs.CharToDrive(gSessionPath[0],driveNum); sl@0: test_KErrNone(r); sl@0: return(driveNum); sl@0: } sl@0: sl@0: GLDEF_C void Format(TInt aDrive) sl@0: // sl@0: // Format current drive sl@0: // 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: 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: LOCAL_C void PushLotsL() sl@0: // sl@0: // Expand the cleanup stack sl@0: // sl@0: { sl@0: TInt i; sl@0: for(i=0;i<1000;i++) sl@0: CleanupStack::PushL((CBase*)NULL); sl@0: CleanupStack::Pop(1000); sl@0: } sl@0: sl@0: sl@0: LOCAL_C void DoTests(TInt aDrive) sl@0: // sl@0: // Do testing on aDrive sl@0: // sl@0: { sl@0: sl@0: gSessionPath=_L("?:\\F32-TST\\"); sl@0: TChar driveLetter; sl@0: TInt r=TheFs.DriveToChar(aDrive,driveLetter); sl@0: test_KErrNone(r); sl@0: gSessionPath[0]=(TText)driveLetter; sl@0: r=TheFs.SetSessionPath(gSessionPath); sl@0: test_KErrNone(r); sl@0: sl@0: User::After(1000000); sl@0: sl@0: // Format(CurrentDrive()); sl@0: sl@0: test.Printf(_L("Creating session path")); sl@0: r=TheFs.MkDirAll(gSessionPath); sl@0: if(r == KErrCorrupt) sl@0: { sl@0: test.Printf(_L("Attempting to create directory \'%S\' failed, KErrCorrupt\n"), &gSessionPath); sl@0: test.Printf(_L("This could be caused by a previous failing test, or a test media defect\n")); sl@0: test.Printf(_L("Formatting drive, retrying MkDirall\nShould subsequent tests fail with KErrCorrupt (%d) as well, replace test medium !\n"), sl@0: r); sl@0: Format(aDrive); sl@0: r=TheFs.MkDirAll(gSessionPath); sl@0: test_KErrNone(r); sl@0: } sl@0: else if (r == KErrNotReady) sl@0: { sl@0: TDriveInfo d; sl@0: r=TheFs.Drive(d, aDrive); sl@0: test_KErrNone(r); sl@0: if (d.iType == EMediaNotPresent) sl@0: test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)driveLetter); sl@0: else sl@0: test.Printf(_L("medium found (type %d) but drive %c: not ready\nPrevious test may have hung; else, check hardware.\n"), (TInt)d.iType, (TUint)driveLetter); sl@0: } sl@0: test_Value(r, r == KErrNone || r == KErrAlreadyExists); sl@0: TheFs.ResourceCountMarkStart(); sl@0: test.Printf(_L("Calling main test sequence ...\n")); sl@0: TRAP(r,CallTestsL()); sl@0: test_KErrNone(r); sl@0: test.Printf(_L("test sequence completed without error\n")); sl@0: TheFs.ResourceCountMarkEnd(); sl@0: sl@0: CheckDisk(); sl@0: } sl@0: sl@0: sl@0: void ParseCommandArguments() sl@0: // sl@0: // sl@0: // sl@0: { sl@0: TBuf<0x100> cmd; sl@0: User::CommandLine(cmd); sl@0: TLex lex(cmd); sl@0: TPtrC token=lex.NextToken(); sl@0: TFileName thisfile=RProcess().FileName(); sl@0: if (token.MatchF(thisfile)==0) sl@0: { sl@0: token.Set(lex.NextToken()); sl@0: } sl@0: test.Printf(_L("CLP=%S\n"),&token); 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: gDriveToTest='C'; sl@0: } sl@0: sl@0: TFullName gExtName; sl@0: TBool gPrimaryExtensionExists = EFalse; sl@0: sl@0: GLDEF_C TInt DismountFileSystem(RFs& aFs, const TDesC& aFileSystemName,TInt aDrive) sl@0: { sl@0: //Make note of the first extension if it exists, so that we remount sl@0: //it when the file system is remounted. sl@0: TInt r = aFs.ExtensionName(gExtName, aDrive, 0); sl@0: sl@0: if (r == KErrNone) sl@0: { sl@0: gPrimaryExtensionExists = ETrue; sl@0: } sl@0: return aFs.DismountFileSystem(aFileSystemName, aDrive); sl@0: } sl@0: sl@0: GLDEF_C TInt MountFileSystem(RFs& aFs, const TDesC& aFileSystemName,TInt aDrive, TBool aIsSync) sl@0: { sl@0: TInt r; sl@0: if (gPrimaryExtensionExists) sl@0: { sl@0: r = aFs.MountFileSystem(aFileSystemName, gExtName, aDrive, aIsSync); sl@0: } sl@0: else sl@0: { sl@0: r = aFs. MountFileSystem(aFileSystemName, aDrive, aIsSync); sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: // sl@0: // Test with drive nearly full sl@0: // sl@0: { sl@0: sl@0: CTrapCleanup* cleanup; sl@0: cleanup=CTrapCleanup::New(); sl@0: TRAPD(r,PushLotsL()); sl@0: __UHEAP_MARK; sl@0: sl@0: test.Title(); sl@0: test.Start(_L("Starting tests...")); sl@0: sl@0: sl@0: ParseCommandArguments(); //need this for drive letter to test sl@0: sl@0: sl@0: r=TheFs.Connect(); sl@0: test_KErrNone(r); sl@0: TheFs.SetAllocFailure(gAllocFailOn); sl@0: TTime timerC; sl@0: timerC.HomeTime(); sl@0: TFileName sessionp; sl@0: TheFs.SessionPath(sessionp); sl@0: sl@0: TBuf<30> privatedir; sl@0: privatedir = KPrivate; sl@0: sl@0: TUid thisUID = RProcess().Identity(); sl@0: privatedir.AppendFormat(_L("%08x"),thisUID.iUid); sl@0: privatedir.Append(_L("\\")); sl@0: sl@0: test(privatedir == sessionp.Mid(2,sessionp.Length()-2)); sl@0: sl@0: test.Printf(_L("sp=%S\n"),&sessionp); sl@0: sessionp[0]=(TText)gDriveToTest; sl@0: test.Printf(_L("sp1=%S\n"),&sessionp); sl@0: sl@0: TInt theDrive; sl@0: r=TheFs.CharToDrive(gDriveToTest,theDrive); sl@0: test_KErrNone(r); sl@0: sl@0: // Get the TFileCacheFlags for this drive sl@0: r = TheFs.Volume(gVolInfo, theDrive); sl@0: if (r == KErrNotReady) sl@0: { sl@0: TDriveInfo info; sl@0: TInt err = TheFs.Drive(info,theDrive); sl@0: test_KErrNone(err); 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: gDriveCacheFlags = gVolInfo.iFileCacheFlags; sl@0: test.Printf(_L("DriveCacheFlags = %08X\n"), gDriveCacheFlags); sl@0: sl@0: #if defined(_DEBUG) || defined(_DEBUG_RELEASE) sl@0: TPckgBuf pkgOrgValues; sl@0: TIOCacheValues& orgValues=pkgOrgValues(); sl@0: r = controlIo(TheFs,theDrive, KControlIoCacheCount, orgValues); sl@0: test_KErrNone(r); sl@0: sl@0: test.Printf(_L("\n")); sl@0: test.Printf(_L("Requests on close queue at start=%d\n"),orgValues.iCloseCount); sl@0: test.Printf(_L("Requests on free queue at start=%d\n"),orgValues.iFreeCount); sl@0: test.Printf(_L("Requests dynamically allocated at start=%d\n"),orgValues.iAllocated); sl@0: test.Printf(_L("Requests in total at start=%d\n"),orgValues.iTotalCount); sl@0: sl@0: // File cache sl@0: sl@0: // flush closed files queue sl@0: r = TheFs.ControlIo(theDrive, KControlIoFlushClosedFiles); sl@0: test_KErrNone(r); sl@0: sl@0: // get number of items on File Cache sl@0: TFileCacheStats startFileCacheStats; sl@0: r = controlIo(TheFs,theDrive, KControlIoFileCacheStats, startFileCacheStats); sl@0: test_Value(r, r == KErrNone || r == KErrNotSupported); sl@0: test.Printf(_L("File cache: Cachelines (free %d, used %d), Segments(allocated %d locked %d). Closed files(%d)\n"), sl@0: startFileCacheStats.iFreeCount, sl@0: startFileCacheStats.iUsedCount, sl@0: startFileCacheStats.iAllocatedSegmentCount, sl@0: startFileCacheStats.iLockedSegmentCount, sl@0: startFileCacheStats.iFilesOnClosedQueue); sl@0: #endif sl@0: sl@0: DoTests(theDrive); sl@0: sl@0: TTime endTimeC; sl@0: endTimeC.HomeTime(); sl@0: TTimeIntervalSeconds timeTakenC; sl@0: r=endTimeC.SecondsFrom(timerC,timeTakenC); sl@0: test_KErrNone(r); sl@0: test.Printf(_L("Time taken for test = %d seconds\n"),timeTakenC.Int()); sl@0: TheFs.SetAllocFailure(gAllocFailOff); sl@0: sl@0: #if defined(_DEBUG) || defined(_DEBUG_RELEASE) sl@0: TPckgBuf pkgValues; sl@0: TIOCacheValues& values=pkgValues(); sl@0: r = controlIo(TheFs,theDrive, KControlIoCacheCount, values); sl@0: test_KErrNone(r); sl@0: sl@0: test.Printf(_L("Requests on close queue at end=%d\n"),values.iCloseCount); sl@0: test.Printf(_L("Requests on free queue at end=%d\n"),values.iFreeCount); sl@0: test.Printf(_L("Requests dynamically allocated at end=%d\n"),values.iAllocated); sl@0: test.Printf(_L("Requests in total at end=%d\n"),values.iTotalCount); sl@0: sl@0: test(orgValues.iCloseCount==values.iCloseCount); sl@0: test(orgValues.iAllocated == values.iAllocated); sl@0: // The free count can increase if the file server runs out of requests in the RequestAllocator sl@0: // free pool but this should never decrease - this implies a request leak sl@0: test(orgValues.iFreeCount <= values.iFreeCount); sl@0: sl@0: // The total number of allocated requests should be equal to : sl@0: // requests on the close queue + requests on free queue sl@0: // + 1 (because we used one request to issue KControlIoCacheCount) sl@0: // If this doesn't equate then this implies a request leak sl@0: test(values.iTotalCount == values.iCloseCount + values.iFreeCount + 1); sl@0: sl@0: // File cache sl@0: TFileCacheStats endFileCacheStats; sl@0: r = controlIo(TheFs,theDrive, KControlIoFileCacheStats, endFileCacheStats); sl@0: test_Value(r, r == KErrNone || r == KErrNotSupported); sl@0: sl@0: test.Printf(_L("File cache: Cachelines (free %d, used %d), Segments(allocated %d locked %d). Closed files(%d)\n"), sl@0: endFileCacheStats.iFreeCount, sl@0: endFileCacheStats.iUsedCount, sl@0: endFileCacheStats.iAllocatedSegmentCount, sl@0: endFileCacheStats.iLockedSegmentCount, sl@0: endFileCacheStats.iFilesOnClosedQueue); sl@0: sl@0: // flush closed files queue sl@0: test.Printf(_L("Flushing close queue...")); sl@0: r = TheFs.ControlIo(theDrive, KControlIoFlushClosedFiles); sl@0: test_KErrNone(r); sl@0: sl@0: r = controlIo(TheFs,theDrive, KControlIoFileCacheStats, endFileCacheStats); sl@0: test_Value(r, r == KErrNone || r == KErrNotSupported); sl@0: test.Printf(_L("File cache: Cachelines (free %d, used %d), Segments(allocated %d locked %d). Closed files(%d)\n"), sl@0: endFileCacheStats.iFreeCount, sl@0: endFileCacheStats.iUsedCount, sl@0: endFileCacheStats.iAllocatedSegmentCount, sl@0: endFileCacheStats.iLockedSegmentCount, sl@0: endFileCacheStats.iFilesOnClosedQueue); sl@0: sl@0: sl@0: if (r == KErrNone) sl@0: { sl@0: test(startFileCacheStats.iFreeCount == endFileCacheStats.iFreeCount); sl@0: test(startFileCacheStats.iUsedCount == endFileCacheStats.iUsedCount); sl@0: test(startFileCacheStats.iAllocatedSegmentCount == endFileCacheStats.iAllocatedSegmentCount); sl@0: test(startFileCacheStats.iLockedSegmentCount == endFileCacheStats.iLockedSegmentCount); sl@0: test(startFileCacheStats.iFileCount == endFileCacheStats.iFileCount); sl@0: } sl@0: #endif sl@0: sl@0: TheFs.Close(); sl@0: test.End(); sl@0: test.Close(); sl@0: __UHEAP_MARKEND; sl@0: delete cleanup; sl@0: return(KErrNone); sl@0: } sl@0: sl@0: