--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/f32test/concur/t_cfssimple.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,504 @@
+// Copyright (c) 1996-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\concur\t_cfssimple.cpp
+//
+//
+#define __E32TEST_EXTENSION__
+#include <f32file.h>
+#include <e32test.h>
+#include "t_server.h"
+#include "t_tdebug.h"
+
+GLDEF_D RTest test(_L("T_CFSSIMPLE"));
+GLDEF_D RFs TheFs;
+
+LOCAL_D TFullName OldFsName;
+LOCAL_D TFileName NewFsName;
+
+_LIT(KFsFile, "CFAFSDLY");
+_LIT(KFsName, "DelayFS");
+
+
+struct TExtension
+ {
+ TFullName iName;
+ TBool iExists;
+ };
+
+LOCAL_D TExtension gPrimaryExtensions[KMaxDrives];
+
+LOCAL_C TChar MountTestFileSystem(TInt aDrive)
+//
+// Mount a new test filesystem on the drive under test
+//
+ {
+ TBuf<64> b;
+ TChar c;
+ TInt r;
+ if (aDrive > EDriveZ)
+ {
+ c = aDrive;
+ r=TheFs.CharToDrive(c, aDrive);
+ test_KErrNone(r);
+ }
+ else
+ {
+ r=TheFs.DriveToChar(aDrive,c);
+ test_KErrNone(r);
+ }
+
+ b.Format(_L("Test mounting of test file system on %c:"),(TUint)c);
+ test.Next(b);
+
+ test.Printf(_L("Load filesystem from %S\n"), &KFsFile);
+
+ r=TheFs.AddFileSystem(KFsFile);
+ test_Value(r, r == KErrNone || r == KErrAlreadyExists);
+
+ r=TheFs.FileSystemName(OldFsName,aDrive);
+ test_Value(r, r == KErrNone || r == KErrNotFound);
+
+ if (OldFsName.Length() > 0)
+ {
+ r = TheFs.ExtensionName(gPrimaryExtensions[aDrive].iName, aDrive, 0);
+ if (r == KErrNone)
+ gPrimaryExtensions[aDrive].iExists = ETrue;
+
+ test.Printf(_L("Dismount %S filesystem on %c:\n"), &OldFsName, (TUint)c);
+ r=TheFs.DismountFileSystem(OldFsName,aDrive);
+ if (r == KErrNotReady)
+ {
+ TDriveInfo d;
+ r=TheFs.Drive(d, aDrive);
+ test_KErrNone(r);
+ if (d.iType == EMediaNotPresent)
+ test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)c);
+ else
+ 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)c);
+ }
+ else if (r == KErrCorrupt)
+ test.Printf(_L("drive %c: corrupted, cannot unmount\nPrevious test may have aborted; else, check hardware.\n"), (TUint)c);
+
+ test_KErrNone(r);
+ }
+
+ test.Printf(_L("Mount filesystem %S\n"), &KFsName);
+
+ if (gPrimaryExtensions[aDrive].iExists == EFalse)
+ r=TheFs.MountFileSystem(KFsName,aDrive);
+ else
+ r=TheFs.MountFileSystem(KFsName,gPrimaryExtensions[aDrive].iName,aDrive);
+ test_KErrNone(r);
+
+ r=TheFs.FileSystemName(NewFsName,aDrive);
+ test_KErrNone(r);
+ test(NewFsName.Compare(KFsName)==0);
+ test.Printf(_L("New %S filesystem on %c:\n"), &NewFsName, (TUint)c);
+
+ // Check attributes
+ TDriveInfo info;
+ r=TheFs.Drive(info,aDrive);
+ test_KErrNone(r);
+
+ test.Printf(_L("iType=%d,iBattery=%d,iDriveAtt=%x,iMediaAtt=%x\n"),(TUint)info.iType,\
+ (TUint)info.iBattery,info.iDriveAtt,info.iMediaAtt);
+ return c;
+ }
+
+LOCAL_C void UnmountFileSystem(TInt aDrive)
+//
+// Unmount the test filesystem on the drive under test
+//
+ {
+ TChar c;
+ TInt r;
+ if (aDrive > EDriveZ)
+ {
+ c = aDrive;
+ r=TheFs.CharToDrive(c, aDrive);
+ test_KErrNone(r);
+ }
+ else
+ {
+ r=TheFs.DriveToChar(aDrive,c);
+ test_KErrNone(r);
+ }
+ test.Printf(_L("Dismount %S filesystem on %c\n"), &NewFsName, (TUint)c);
+ r=TheFs.DismountFileSystem(NewFsName,aDrive);
+ test_KErrNone(r);
+ if (OldFsName.Length() > 0)
+ {
+ test.Printf(_L("Remount %S filesystem on %c\n"), &OldFsName, (TUint)c);
+
+ if (gPrimaryExtensions[aDrive].iExists == EFalse)
+ r=TheFs.MountFileSystem(OldFsName,aDrive);
+ else
+ r=TheFs.MountFileSystem(OldFsName,gPrimaryExtensions[aDrive].iName,aDrive);
+ test_KErrNone(r);
+ }
+ }
+
+template <TInt N>
+LOCAL_C TDes* cvtbuff(const TDesC8& buff, TBuf<N>& b)
+//
+// Copy an 8-bit buffer to a character one.
+//
+ {
+ TInt i;
+ TInt len = buff.Length();
+ TInt max = b.MaxLength();
+ if (len > max)
+ len = max;
+ b.SetLength(len);
+ for (i = 0; i < len; i++)
+ b[i] = TText(buff[i]);
+ return &b;
+ }
+
+//---------------------------------------------
+//! @SYMTestCaseID FSBASE-CR-PCHY-6PALT2
+//! @SYMTestType CT
+//! @SYMREQ CR PCHY-6PALT2
+//! @SYMTestCaseDesc Test asynchronous RFs::Flush(TRequestStatus& aStatus)
+//! @SYMTestStatus Implemented
+//! @SYMTestActions Perform an asynchronous flush and wait for completion
+//! @SYMTestExpectedResults Asynchronous flush completes after expected delay
+//! @SYMTestPriority Low
+//! @SYMAuthor Stefan Williams
+//! @SYMCreationDate 01/06/2006
+//! @See EFSRV and EFILE components
+//! @file f32test\concur\t_cfssimple.cpp
+//---------------------------------------------
+
+LOCAL_C void testAsyncFlush(RFile& aFile)
+ {
+ TTest::Printf(_L("Test Async RFile::Flush()"));
+
+ RTimer flushTimer;
+ TRequestStatus flushTimerStatus;
+ TInt err = flushTimer.CreateLocal();
+ TEST(err == KErrNone);
+
+ flushTimer.After(flushTimerStatus, 10000000); // 10 seconds timeout for RFile::Flush on CFAFSDLY file system
+
+ TTime startFlush;
+ startFlush.HomeTime();
+
+ TRequestStatus flushStatus;
+ aFile.Flush(flushStatus);
+ TEST(flushStatus==KRequestPending);
+
+ User::WaitForRequest(flushTimerStatus, flushStatus);
+ if ((flushStatus == KRequestPending) && (flushTimerStatus == KErrNone))
+ {
+ TTest::Fail(HERE, _L("Flush : Timed Out"));
+ }
+
+ if (flushStatus != KErrNone)
+ {
+ TTest::Fail(HERE, flushStatus.Int(), _L("Flush : Error"));
+ }
+
+ TTime endFlush;
+ endFlush.HomeTime();
+
+ TTimeIntervalSeconds flushTime;
+ err = endFlush.SecondsFrom(startFlush, flushTime);
+ TEST(err == KErrNone);
+
+ TTest::Printf(_L("Flush took %d seconds"), flushTime.Int());
+
+ if(flushTime.Int() < 3)
+ {
+ TTest::Fail(HERE, _L("Flush took < 3 Seconds"));
+ }
+
+ flushTimer.Cancel();
+ flushTimer.Close();
+ }
+
+LOCAL_C TInt testAccessFile(TAny*)
+//
+// Test read file handling with two threads.
+//
+ {
+ TTest::Start(_L("Test write file"));
+
+ TThreadData& data = TTest::Self();
+ TFileName fileName = data.iFile;
+
+ TTest::Printf(_L("Connect to myFs\n"));
+
+ RFs myFs;
+ TInt r = myFs.Connect();
+ TEST(r==KErrNone);
+
+ TTest::Printf(_L("Create %S\n"), &fileName);
+
+ RFile f;
+
+ r = f.Replace(myFs, fileName, EFileStreamText | EFileWrite);
+ TEST(r==KErrNone);
+
+ // wait for both tasks to have a chance to complete opening the files
+ User::After(1000);
+
+ const TInt KNumBuf = 10;
+ const TInt KBufLen = 0x80;
+ TBuf8<KBufLen> a[KNumBuf];
+ TBuf8<KBufLen> b;
+ TBuf<KBufLen> tbuf;
+ TInt i;
+
+ TUint base = 0;
+ for (i = 0; i < fileName.Length(); i++)
+ base = base * 0x11 + fileName[i];
+ base += base / 32;
+ base = base % 32 + 0x30;
+
+ TRequestStatus status[10];
+
+ TTest::Next(_L("Write file"));
+ for (i = 0; i <= 9; i++)
+ {
+ TChar val = TChar(base + i);
+ a[i].Fill(TText(val), i+1);
+ TTest::Printf(_L("write '%S' started\n"), cvtbuff(a[i], tbuf));
+ f.Write(a[i], status[i]);
+ User::After(1);
+ if (r != KErrNone)
+ {
+ TTest::Fail(HERE, r, _L("Write"));
+ }
+ }
+
+ for (i = 0; i < 10; i++)
+ {
+ User::WaitForAnyRequest();
+ if (status[i] == KRequestPending)
+ {
+ TTest::Printf(_L("write %d still pending!\n"), i);
+ }
+ else
+ {
+ TTest::Printf(_L("write %d completed with status %d\n"), i, status[i].Int());
+ }
+ }
+
+ TTest::Printf(_L("Write 64 bytes at the end as padding\n"));
+ TBuf8<32> fill;
+ fill.Fill(TText('_'), 32);
+ f.Write(fill);
+ f.Write(fill);
+
+ testAsyncFlush(f);
+
+ f.Close();
+
+ b.Fill(TText('*'), b.MaxLength());
+ TTest::Next(_L("Read file"));
+
+ // wait to allow the dust to settle
+ User::After(1000000);
+
+ r = f.Open(myFs, fileName, EFileStreamText);
+ TEST(r==KErrNone);
+
+ for (i = 0; i < 10; i++)
+ {
+ r=f.Read(b, 12-i);
+ if (r == KErrNone)
+ {
+ TTest::Printf(_L("read %2d bytes <%S>\n"), b.Length(), cvtbuff(b, tbuf));
+ }
+ else
+ {
+ TTest::Fail(HERE, r, _L("Read"));
+ }
+ User::After(1);
+ }
+ r=f.Read(b);
+ if (r != KErrNone)
+ {
+ TTest::Fail(HERE, r, _L("Read\n"));
+ // TEST(r==KErrNone);
+ }
+ if (!(b.Length()==0))
+ {
+ cvtbuff(b, tbuf);
+ TTest::Printf(_L("read %2d bytes <%.32S>\n"), b.Length(), &tbuf);
+ }
+
+ // wait to allow the dust to settle
+ User::After(1000000);
+
+ TTest::Printf(_L("Close file"));
+ f.Close();
+
+ TTest::Printf(_L("Close session"));
+ myFs.Close();
+ return r;
+ }
+
+LOCAL_C TInt createThread(TThreadFunction aFunc, TChar aDrvCh)
+//
+// Create a thread using function aFunc on drive aDrvCh
+//
+ {
+ static TInt tnum = 0;
+ TBuf<2> drive(_L("?"));
+ TBuf<64> name;
+ drive[0] = TText(aDrvCh);
+ drive.UpperCase();
+ TThreadData& d = TTest::Data(tnum);
+ d.iFile.Format(_L("%S:\\TEST%d.FILE"), &drive, tnum);
+ name.Format(_L("Test_%S_%d"), &drive, tnum);
+ TInt r = TTest::Create(tnum, aFunc, name);
+ ++tnum;
+ return r;
+ }
+
+LOCAL_C TInt testThreads(TChar aDrvCh1, TChar aDrvCh2)
+//
+// Create threads operating on files on two drives.
+//
+ {
+ TInt r;
+ r = createThread(testAccessFile, aDrvCh1);
+ r = createThread(testAccessFile, aDrvCh2);
+ r = TTest::Run();
+ return r;
+ }
+
+LOCAL_C TBool isSpace(TChar c)
+//
+// Return true if the character is space or tab
+//
+ {
+ return (c == ' ' || c == '\t');
+ }
+
+LOCAL_C void parseCmd(TDesC& cmd, TChar& dr0, TChar& dr1, TChar& dr2)
+//
+// Parse command line to get two characters for drive 1 and 2
+//
+ {
+ TInt i = 0;
+ TInt n = cmd.Length();
+ // skip to first non-space
+ while (i < n && isSpace(cmd[i]))
+ ++i;
+ if (i < n)
+ dr0 = cmd[i];
+ // skip to first space
+ while (i < n && !isSpace(cmd[i]))
+ ++i;
+ // skip to first non-space
+ while (i < n && isSpace(cmd[i]))
+ ++i;
+ if (i < n)
+ dr1 = cmd[i];
+ // skip to first space
+ while (i < n && !isSpace(cmd[i]))
+ ++i;
+ // skip to first non-space
+ while (i < n && isSpace(cmd[i]))
+ ++i;
+ if (i < n)
+ dr2 = cmd[i];
+ // skip to first space
+ while (i < n && !isSpace(cmd[i]))
+ ++i;
+ }
+
+GLDEF_C void CallTestsL()
+//
+// Do all tests
+//
+ {
+ TBuf<0x100> cmd;
+ User::CommandLine(cmd);
+ cmd.UpperCase();
+
+ TChar dr0 = 'F';
+ TChar dr1 = 0;
+ TChar dr2 = 0;
+ parseCmd(cmd, dr0, dr1, dr2);
+
+ if (dr1 < 'A')
+ dr1 = dr0;
+
+ if (dr2 < 'A')
+ dr2 = dr1;
+
+ if (dr0 < 'A' || dr0 >= 'Z')
+ {
+ test.Printf(_L("Test cannnot run on drive\n"));
+ return;
+ }
+
+ MountTestFileSystem(dr0);
+ // TheFs.SetVolumeLabel(_L("TRACE"));
+ TInt r = testThreads(dr1, dr2);
+ TheFs.SetVolumeLabel(_L("OFF"));
+ UnmountFileSystem(dr0);
+ test_KErrNone(r);
+ }
+
+GLDEF_C TInt E32Main()
+//
+// Main entry point
+//
+ {
+
+ for (TInt i = 0; i < KMaxDrives; i++)
+ {
+ gPrimaryExtensions[i].iExists = EFalse;
+ }
+
+ TInt r;
+ CTrapCleanup* cleanup;
+ cleanup=CTrapCleanup::New();
+ __UHEAP_MARK;
+
+ test.Title();
+ test.Start(_L("Starting tests..."));
+
+ r=TheFs.Connect();
+ test_KErrNone(r);
+
+ // TheFs.SetAllocFailure(gAllocFailOn);
+ TTime timerC;
+ timerC.HomeTime();
+
+ TRAP(r,CallTestsL());
+
+ // reset the debug register
+ TheFs.SetDebugRegister(0);
+
+ TTime endTimeC;
+ endTimeC.HomeTime();
+ TTimeIntervalSeconds timeTakenC;
+ r=endTimeC.SecondsFrom(timerC,timeTakenC);
+ test_KErrNone(r);
+ test.Printf(_L("Time taken for test = %d seconds\n"),timeTakenC.Int());
+ // TheFs.SetAllocFailure(gAllocFailOff);
+ TheFs.Close();
+ test.End();
+ test.Close();
+ __UHEAP_MARKEND;
+ delete cleanup;
+ return(KErrNone);
+ }
+