sl@0: // Copyright (c) 2008-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_notifier.cpp sl@0: // sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "t_server.h" sl@0: #include "t_chlffs.h" sl@0: #include "t_notify_plugin.h" sl@0: sl@0: const TInt KNotificationHeaderSize = (sizeof(TUint16)*2)+(sizeof(TUint)); sl@0: const TInt KMinNotificationBufferSize = 2*KNotificationHeaderSize + 2*KMaxFileName; sl@0: sl@0: sl@0: RTest test(_L("T_NOTIFIER")); sl@0: const TInt KMaxHeapSize = 0x800000; sl@0: TInt globalDriveNum; sl@0: sl@0: void DismountPlugin() sl@0: { sl@0: TheFs.DismountPlugin(KNotifyPluginName); sl@0: TheFs.RemovePlugin(KNotifyPluginFileName); sl@0: } sl@0: sl@0: inline void safe_test(RTest& aTest, TInt aError, TInt aLine, TText* aName) sl@0: { sl@0: if(aError!=KErrNone) sl@0: { sl@0: test.Printf(_L(": ERROR : %d received on line %d\n"),aError,aLine); sl@0: DismountPlugin(); sl@0: aTest.operator()(aError==KErrNone,aLine,(TText*)aName); sl@0: } sl@0: } sl@0: sl@0: // Used by TestMultipleNotificationsL() to show which line the function is called from sl@0: inline void safe_test(RTest& aTest, TInt aError, TInt aLine, TInt aLineCall) sl@0: { sl@0: if(aError != KErrNone) sl@0: { sl@0: aTest.Printf(_L(": ERROR : %d received on line %d\n"), aError, aLine); sl@0: aTest.Printf(_L(": ERROR : Function called from line number: %d\n"), aLineCall); sl@0: aTest.operator()(aError == KErrNone, aLine); sl@0: } sl@0: } sl@0: sl@0: // Prints out the filename sl@0: #define ExpandMe(X) L ## X sl@0: #define Expand(X) ExpandMe(X) sl@0: sl@0: namespace t_notification sl@0: { sl@0: enum EOperation sl@0: { sl@0: //TFsNotification::ECreate sl@0: EFileReplace, sl@0: EFileCreate, sl@0: EFileCreate_subs, //Create files in subdir, watch subdirs sl@0: EFileCreate_subs_nowatch, //Create files in subdir, do not monitor subdirs sl@0: EFileCreate_txt_nowatch, //Create .txt files in subdir, do not monitor subdirs sl@0: EFileCreate_txt, //Create .txt files sl@0: EFsMkDir, //Create directory sl@0: //TFsNotification::EAttribute sl@0: EFileSetAtt, sl@0: EFileSetAtt_subs, //Set attributes in subdir sl@0: EFileSet, sl@0: EFsSetEntry, sl@0: //TFsNotification::ERename sl@0: EFsReplace, //Replace file sl@0: EFsRename, //Rename file sl@0: EFsRename_dir, //Rename directory sl@0: EFileRename, sl@0: EFileRename_wild, //Rename file using wildcard name sl@0: //TFsNotification::EDelete sl@0: EFsDelete, //Delete file sl@0: EFsRmDir, //Remove directory sl@0: EFsRmDir_nonEmpty, //Remove non-empty directory, which will return KErrInUse sl@0: EFsRmDir_wild, //Remove subdirectory using wildcard name sl@0: //TFsNotification::EFileChange sl@0: EFileWrite, sl@0: EFileWrite_samesize, //Write to file without changing its size sl@0: EFileWrite_async, //Asynchronous write sl@0: EFileSetSize, sl@0: //TFsNotification::EVolumeName sl@0: ESetVolumeLabel, sl@0: //TFsNotification::EDriveName sl@0: ESetDriveName, sl@0: //TFsNotification::EMediaChange sl@0: EMount, sl@0: EDismount, sl@0: EMountScan, sl@0: EMountDismount, sl@0: EFormat, sl@0: EMediaCardRemoval, sl@0: EMediaCardInsertion, sl@0: ERawDiskWrite, sl@0: //Multiple Filters sl@0: EAllOps1, //Create/Replace and Delete sl@0: EAllOps2, //Create/Replace, FileChange(Write) and Delete sl@0: EAllOps3, //Create/Replace, FileChange(SetSize) and Delete sl@0: EAllOps4, //Create/Replace, Attribute(SetAtt) and Delete sl@0: EAllOps5, //Create/Replace and Rename sl@0: EAllOps6, //VolumeName and DriveName sl@0: ECFileManMove //Create filex in monitored directory, write 4, move to unmonitored, setsize 8, move back, delete sl@0: }; sl@0: } sl@0: sl@0: // Package filename and semaphore for thread sl@0: struct SThreadPackage sl@0: { sl@0: TFileName iFileName; sl@0: RSemaphore iBarrier; sl@0: }; sl@0: sl@0: struct SThreadPackageDualSemaphore sl@0: { sl@0: TFileName iFileName; sl@0: RSemaphore iBarrier; sl@0: RSemaphore iBarrier2; sl@0: }; sl@0: sl@0: struct SThreadPackage2 sl@0: { sl@0: TInt iTestCase; sl@0: RSemaphore iBarrier; sl@0: }; sl@0: sl@0: // Used by TestMultipleNotificationsL sl@0: struct SThreadPackageMultiple sl@0: { sl@0: TFileName iString; //Commonly stores the filename sl@0: TFileName iFileName; //Commonly stores the path (not inc filename) sl@0: RSemaphore iBarrier; sl@0: t_notification::EOperation iOperation; sl@0: TFsNotification::TFsNotificationType iNotifyType; sl@0: TInt iIterations; //# of times to 'do' something sl@0: TInt iMaxNotifications; //# of notifications expected sl@0: TInt iBufferSize; sl@0: TInt iLineCall; //Line where the function is called from sl@0: }; sl@0: sl@0: void PrintLine() sl@0: { sl@0: test.Printf(_L("======================================================================\n")); sl@0: } sl@0: sl@0: sl@0: // We should receive an EMediaChange notification even though we did not register for it sl@0: void TestMediaCardNotificationWhenNotRegisteredForIt() sl@0: { sl@0: RFs fs; sl@0: TInt r = fs.Connect(); sl@0: test(r==KErrNone); sl@0: sl@0: CFsNotify* notify = NULL; sl@0: TRAP(r,notify= CFsNotify::NewL(fs,KMinNotificationBufferSize)); sl@0: sl@0: TBuf<40> path; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: sl@0: TBuf<20> filename; sl@0: filename.Append(_L("media.change1")); sl@0: sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,path,filename); sl@0: test(r==KErrNone); sl@0: sl@0: TRequestStatus status; sl@0: r = notify->RequestNotifications(status); sl@0: test(r==KErrNone); sl@0: sl@0: test.Printf(_L("*****************************************************************\n")); sl@0: test.Printf(_L("Waiting 10 seconds.\n")); sl@0: test.Printf(_L("This is a MANUAL test, it requires the removal of the media card.\n")); sl@0: test.Printf(_L("PLEASE REMOVE THE MEDIA CARD. (DriveNumber %d)\n"),globalDriveNum); sl@0: test.Printf(_L("Or press Ctrl + F5 on the emulator.\n")); sl@0: test.Printf(_L("*****************************************************************\n")); sl@0: RTimer timer1; sl@0: r = timer1.CreateLocal(); sl@0: test(r == KErrNone); sl@0: TRequestStatus timeout; sl@0: TTimeIntervalMicroSeconds32 time = 10000000; sl@0: timer1.After(timeout,time); sl@0: User::WaitForRequest(timeout,status); sl@0: test(status.Int() != KRequestPending); sl@0: timer1.Cancel(); sl@0: timer1.Close(); sl@0: sl@0: const TFsNotification* notification = notify->NextNotification(); sl@0: test(notification != NULL); sl@0: TFsNotification::TFsNotificationType type = notification->NotificationType(); sl@0: test(type == TFsNotification::EMediaChange); sl@0: TBuf<2> drive; sl@0: drive.Append((TChar)gDriveToTest); sl@0: drive.Append(_L(":")); sl@0: TPtrC drivePtr; sl@0: r = notification->Path(drivePtr); sl@0: test(r==KErrNone); sl@0: r = drivePtr.Compare(drive); sl@0: test(r==0); sl@0: sl@0: test.Printf(_L("*****************************************************************\n")); sl@0: test.Printf(_L("Waiting 10 seconds.\n")); sl@0: test.Printf(_L("This is a MANUAL test, it requires the insertion of the media card.\n")); sl@0: test.Printf(_L("PLEASE INSERT THE MEDIA CARD. (DriveNumber %d)\n"),globalDriveNum); sl@0: test.Printf(_L("Or press Ctrl + F5 on the emulator.\n")); sl@0: test.Printf(_L("*****************************************************************\n")); sl@0: sl@0: notification = notify->NextNotification(); sl@0: if(notification == NULL) sl@0: { sl@0: notify->RequestNotifications(status); sl@0: RTimer timer2; sl@0: r = timer2.CreateLocal(); sl@0: test(r == KErrNone); sl@0: TRequestStatus timeout2; sl@0: timer2.After(timeout2,time); sl@0: User::WaitForRequest(timeout2,status); sl@0: test(status.Int() != KRequestPending); sl@0: notification = notify->NextNotification(); sl@0: timer2.Cancel(); sl@0: timer2.Close(); sl@0: } sl@0: test(notification != NULL); sl@0: type = notification->NotificationType(); sl@0: test(type == TFsNotification::EMediaChange); sl@0: sl@0: delete notify; sl@0: fs.Close(); sl@0: } sl@0: sl@0: // Creates two sessions, removes the first one sl@0: // and then checks if the second one still works sl@0: TInt TestClientRemovalL() sl@0: { sl@0: RFs fs; sl@0: TInt r = fs.Connect(); sl@0: test(r==KErrNone); sl@0: sl@0: CFsNotify* notify1 = NULL; sl@0: CFsNotify* notify2 = NULL; sl@0: TRAP(r,notify1= CFsNotify::NewL(fs,KMinNotificationBufferSize); sl@0: notify2= CFsNotify::NewL(fs,KMinNotificationBufferSize); sl@0: ); sl@0: if(r!=KErrNone) sl@0: { sl@0: delete notify1; sl@0: delete notify2; sl@0: test(r==KErrNone); sl@0: } sl@0: sl@0: TBuf<40> path; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: sl@0: TBuf<15> filename; sl@0: filename.Append(_L("create.file")); sl@0: sl@0: TBuf<40> fullname; sl@0: fullname.Append(path); sl@0: fullname.Append(filename); sl@0: sl@0: r = notify1->AddNotification((TUint)TFsNotification::ECreate,path,filename); sl@0: test(r==KErrNone); sl@0: r = notify2->AddNotification((TUint)TFsNotification::ECreate,path,filename); sl@0: test(r==KErrNone); sl@0: sl@0: delete notify1; //Delete notify1 and ensure we still get notification on notify2 sl@0: sl@0: TRequestStatus status; sl@0: r = notify2->RequestNotifications(status); sl@0: test(r==KErrNone); sl@0: sl@0: RFile file; sl@0: file.Replace(fs,fullname,EFileWrite); //Replace produces Create notification sl@0: file.Close(); sl@0: sl@0: RTimer tim; sl@0: r = tim.CreateLocal(); sl@0: test(r==KErrNone); sl@0: sl@0: TRequestStatus timStatus; sl@0: TTimeIntervalMicroSeconds32 time = 10000000; //10 seconds sl@0: tim.After(timStatus,time); sl@0: sl@0: User::WaitForRequest(status,timStatus); sl@0: test(status!=KRequestPending); sl@0: sl@0: r = fs.Delete(fullname); sl@0: test(r==KErrNone); sl@0: sl@0: delete notify2; sl@0: tim.Close(); sl@0: fs.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * This tests that u can set and receive notifications in the root sl@0: * of a drive. sl@0: * sl@0: * (something which was apparently not possible on RFs::NotifyChange) sl@0: */ sl@0: TInt TestRootDriveNotifications() sl@0: { sl@0: test.Next(_L("TestRootDriveNotifications")); sl@0: RFs fs; sl@0: fs.Connect(); sl@0: sl@0: CFsNotify* notify = NULL; sl@0: sl@0: TRAPD(r,notify = CFsNotify::NewL(fs,KMinNotificationBufferSize);); sl@0: test(r==KErrNone); sl@0: test(notify!=NULL); sl@0: sl@0: TBuf<40> path; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\")); sl@0: sl@0: TBuf<15> filename; sl@0: filename.Append(_L("*")); sl@0: sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,path,filename); sl@0: test(r==KErrNone); sl@0: sl@0: TRequestStatus status; sl@0: r = notify->RequestNotifications(status); sl@0: test(r==KErrNone); sl@0: sl@0: RFile file; sl@0: TBuf<40> filePath; sl@0: filePath.Append((TChar)gDriveToTest); sl@0: filePath.Append(_L(":\\file.root")); sl@0: r = file.Replace(fs,filePath,EFileRead); sl@0: test(r==KErrNone); sl@0: file.Close(); sl@0: sl@0: TRequestStatus s2; sl@0: RTimer tim; sl@0: test(tim.CreateLocal()==KErrNone); sl@0: TTimeIntervalMicroSeconds32 time = 10000000; //10 seconds sl@0: tim.After(s2,time); sl@0: User::WaitForRequest(status,s2); sl@0: test(status!=KRequestPending); sl@0: sl@0: delete notify; sl@0: notify = NULL; sl@0: tim.Close(); sl@0: fs.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * Creates and deletes loads of CFsNotify objects and makes sure they're all sl@0: * cleaned up afterwards. sl@0: */ sl@0: TInt TestNewDeleteCFsNotify(TInt aIterations) sl@0: { sl@0: RPointerArray array; sl@0: TInt inArray = 0; sl@0: TInt r = KErrNone; sl@0: for(TInt i = 0; i < aIterations; i++) sl@0: { sl@0: CFsNotify* notify = NULL; sl@0: TRAP(r,notify = CFsNotify::NewL(TheFs,500)); sl@0: if(r==KErrNone) sl@0: { sl@0: test(notify!=NULL); sl@0: r = array.Append(notify); sl@0: if(r==KErrNone) sl@0: { sl@0: inArray++; sl@0: } sl@0: else sl@0: { sl@0: delete notify; sl@0: break; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: break; sl@0: } sl@0: } sl@0: sl@0: for(TInt j = inArray-1; j >= 0; j--) sl@0: { sl@0: CFsNotify* notify = (CFsNotify*)array[j]; sl@0: array.Remove(j); sl@0: delete notify; sl@0: } sl@0: sl@0: array.Reset(); sl@0: array.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: /* sl@0: * Creates a file sl@0: * Used in SimpleTest1L(), TestTwoDoersL() TestTwoWatchersL(), TestCancelNotificationL() sl@0: */ sl@0: TInt SimpleSingleNotificationTFDoer(TAny* aAny) sl@0: { sl@0: SThreadPackageDualSemaphore pkgDoer = *(SThreadPackageDualSemaphore*)aAny; sl@0: RTest simpleTestDoer(_L("SimpleSingleNotificationTFDoer")); sl@0: simpleTestDoer.Start(_L("SimpleSingleNotificationTFDoer")); sl@0: TBuf<40> path; sl@0: path.Append(gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: path.Append(pkgDoer.iFileName); sl@0: sl@0: //Delete file so we definitely get a create notification sl@0: RFs fs; sl@0: TInt r = fs.Connect(); sl@0: safe_test(simpleTestDoer,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: r = fs.Delete(path); sl@0: if(r==KErrNone || r==KErrPathNotFound || r==KErrNotFound) sl@0: r = KErrNone; sl@0: safe_test(simpleTestDoer,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: r = fs.MkDirAll(path); sl@0: if(r==KErrNone || r==KErrAlreadyExists) sl@0: r = KErrNone; sl@0: safe_test(simpleTestDoer,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: sl@0: simpleTestDoer.Printf(_L("SimpleSingleNotificationTFDoer - Create File %S\n"),&path); sl@0: //Create file sl@0: RFile file; sl@0: r = file.Create(fs,path,EFileWrite); sl@0: safe_test(simpleTestDoer,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: file.Close(); sl@0: sl@0: fs.Close(); sl@0: simpleTestDoer.End(); sl@0: simpleTestDoer.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * Watches 1 file creation sl@0: * Used in SimpleTest1L() sl@0: */ sl@0: TInt SimpleSingleNotificationTFWatcher(TAny* aAny) sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: RThread thread; sl@0: TUint64 threadId = thread.Id().Id(); sl@0: sl@0: SThreadPackage pkgDoer = *(SThreadPackage*)aAny; sl@0: RSemaphore& simpleBarrierTest = pkgDoer.iBarrier; sl@0: sl@0: RTest simpleTestWatcher(_L("SimpleSingleNotificationTFWatcher")); sl@0: simpleTestWatcher.Start(_L("SimpleSingleNotificationTFWatcher")); sl@0: sl@0: RFs fs; sl@0: fs.Connect(); sl@0: sl@0: simpleTestWatcher.Printf(_L("SimpleSingleNotificationTFWatcher(%d) - Create CFsNotify\n"),threadId); sl@0: CFsNotify* notify = NULL; sl@0: TRAPD(r,notify = CFsNotify::NewL(fs,100); ); sl@0: safe_test(simpleTestWatcher,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: TBuf<40> path; sl@0: path.Append(gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); //len=22 sl@0: sl@0: TBuf<20> filename; sl@0: filename.Append(pkgDoer.iFileName); sl@0: sl@0: TBuf<40> fullname; sl@0: fullname.Append(path); sl@0: fullname.Append(filename); sl@0: sl@0: simpleTestWatcher.Printf(_L("SimpleSingleNotificationTFWatcher - Add Notification for %S\n"),&path); sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,path,filename); sl@0: safe_test(simpleTestWatcher,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: TRequestStatus status; sl@0: simpleTestWatcher.Printf(_L("SimpleSingleNotificationTFWatcher(%d) - Request Notifications\n"),threadId); sl@0: r = notify->RequestNotifications(status); sl@0: safe_test(simpleTestWatcher,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: sl@0: simpleBarrierTest.Signal(); sl@0: sl@0: simpleTestWatcher.Printf(_L("SimpleSingleNotificationTFWatcher(%d) - Wait for status to return\n"),threadId); sl@0: User::WaitForRequest(status); sl@0: sl@0: simpleTestWatcher.Printf(_L("(%d) NextNotification\n"),threadId); sl@0: const TFsNotification* notification = notify->NextNotification(); sl@0: //Test notification is not null. sl@0: //We should be getting 1 notification. sl@0: if(notification == NULL) sl@0: safe_test(simpleTestWatcher,KErrNotFound,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: sl@0: simpleTestWatcher.Printf(_L("(%d) - Notification Type\n"),threadId); sl@0: TFsNotification::TFsNotificationType notificationType = ((TFsNotification*)notification)->NotificationType(); sl@0: if(notificationType != TFsNotification::ECreate) sl@0: safe_test(simpleTestWatcher,KErrGeneral,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: simpleTestWatcher.Printf(_L("(%d) - Notification Path\n"),threadId); sl@0: TPtrC _pathC; sl@0: ((TFsNotification*)notification)->Path(_pathC); sl@0: simpleTestWatcher.Printf(_L("Notification Path = %S\n"),&_pathC); sl@0: TBuf<40> _path; sl@0: _path.Copy(_pathC); sl@0: if(_path.Match(fullname)!=KErrNone) sl@0: safe_test(simpleTestWatcher,KErrBadName,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: sl@0: /* sl@0: TInt driveNumber = 0; sl@0: TInt gDriveNum = -1; sl@0: notification->DriveNumber(driveNumber); sl@0: RFs::CharToDrive(_pathC[0],gDriveNum); sl@0: if(driveNumber != gDriveNum) sl@0: safe_test(simpleTestWatcher,KErrBadHandle,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: sl@0: TUid uid; sl@0: TUint32 realUID = 0x76543210; sl@0: r = notification->UID(uid); sl@0: safe_test(simpleTestWatcher,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: safe_test(simpleTestWatcher,(realUID == uid.iUid)==1,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: */ sl@0: delete notify; sl@0: fs.Close(); sl@0: simpleTestWatcher.End(); sl@0: simpleTestWatcher.Close(); sl@0: delete cleanup; sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * SimpleTest1L - Runs a simple Create test, gets 1 notification, calls type, path etc and exits sl@0: * Two threads: 1 watcher, 1 doer sl@0: */ sl@0: TInt SimpleCreateTestL() sl@0: { sl@0: test.Next(_L("SimpleTest")); sl@0: RFs fs; sl@0: fs.Connect(); sl@0: _LIT(KFileName,"simple.create"); sl@0: SThreadPackage pkgDoer; sl@0: pkgDoer.iFileName = KFileName; sl@0: sl@0: SThreadPackage watcherPkg; sl@0: watcherPkg.iFileName = KFileName; sl@0: User::LeaveIfError(pkgDoer.iBarrier.CreateLocal(0)); sl@0: User::LeaveIfError(watcherPkg.iBarrier.CreateLocal(0)); sl@0: RThread watcher; sl@0: RThread doer; sl@0: watcher.Create(_L("Simple1WatcherThread"),SimpleSingleNotificationTFWatcher,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&watcherPkg); sl@0: doer.Create(_L("Simple1DoerThread"),SimpleSingleNotificationTFDoer,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&pkgDoer); sl@0: watcher.Resume(); sl@0: watcherPkg.iBarrier.Wait(); //Wait till Watcher has requested notification sl@0: doer.Resume(); sl@0: sl@0: TRequestStatus status; sl@0: doer.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test.Printf(_L("SimpleCreateTest - Doer Exit Reason = %d\n"),doer.ExitReason()); sl@0: safe_test(test,doer.ExitReason(),__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: sl@0: RDebug::Print(_L("Line %d"),__LINE__); sl@0: sl@0: sl@0: watcher.Logon(status); sl@0: RTimer timer1; sl@0: TInt r = timer1.CreateLocal(); sl@0: safe_test(test,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: TRequestStatus timeout; sl@0: TTimeIntervalMicroSeconds32 time = 10000000; //10 seconds sl@0: timer1.After(timeout,time); sl@0: User::WaitForRequest(timeout,status); sl@0: test(status.Int() != KRequestPending); sl@0: timer1.Cancel(); sl@0: timer1.Close(); sl@0: sl@0: sl@0: // User::WaitForRequest(status); sl@0: test.Printf(_L("SimpleCreateTest - Watcher Exit Reason = %d\n"),watcher.ExitReason()); sl@0: safe_test(test,watcher.ExitReason(),__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: sl@0: CLOSE_AND_WAIT(doer); sl@0: CLOSE_AND_WAIT(watcher); sl@0: sl@0: pkgDoer.iBarrier.Close(); sl@0: watcherPkg.iBarrier.Close(); sl@0: fs.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: // Doer thread for TestMultipleNotificationsL sl@0: TInt MultipleNotificationTFDoer(TAny* aAny) sl@0: { sl@0: RDebug::Print(_L("MultipleNotificationTFDoer - Start, Line %d"), __LINE__); sl@0: SThreadPackageMultiple pkgDoer = *(SThreadPackageMultiple*)aAny; sl@0: RTest multipleTestDoer(_L("MultipleNotificationTFDoer")); sl@0: multipleTestDoer.Start(_L("Multi-Doer")); sl@0: multipleTestDoer.Printf(_L("MultipleNotificationTFDoer - Line %d"),__LINE__); sl@0: TBuf<40> basepath; sl@0: basepath.Append(gDriveToTest); sl@0: basepath.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: sl@0: RThread thread; sl@0: RDebug::Print(_L("MultipleNotificationTFDoer - Line %d"), __LINE__); sl@0: TUint64 threadID = thread.Id().Id(); sl@0: RDebug::Print(_L("MultipleNotificationTFDoer - Line %d"), __LINE__); sl@0: sl@0: //Delete file so we definitely get a create notification sl@0: RFs fs; sl@0: TInt r = fs.Connect(); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: TEntry entry; sl@0: TBool wildcard = EFalse; sl@0: TBuf<40> _path; sl@0: _path.Append(basepath); sl@0: _path.Append(pkgDoer.iFileName); sl@0: _path.Append(pkgDoer.iString); sl@0: r = fs.Entry(_path, entry); sl@0: if (pkgDoer.iNotifyType != TFsNotification::EMediaChange && sl@0: pkgDoer.iNotifyType != TFsNotification::EDriveName && sl@0: pkgDoer.iNotifyType != TFsNotification::EVolumeName && sl@0: pkgDoer.iOperation != t_notification::EAllOps6) sl@0: { sl@0: if (r == KErrBadName) sl@0: { sl@0: wildcard = ETrue; sl@0: } sl@0: if(r != KErrNone && r != KErrPathNotFound && r != KErrNotFound && r != KErrBadName) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: if (r == KErrNone && !entry.IsDir() && pkgDoer.iOperation != t_notification::EFsDelete && !wildcard && sl@0: pkgDoer.iOperation != t_notification::EFsRmDir && pkgDoer.iOperation != t_notification::EFsRmDir_nonEmpty) sl@0: { sl@0: r = fs.Delete(_path); sl@0: if(r != KErrNone && r != KErrPathNotFound && r != KErrNotFound) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: r = fs.MkDirAll(basepath); sl@0: if(r != KErrNone && r != KErrAlreadyExists) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: sl@0: multipleTestDoer.Printf(_L("MultipleNotificationTFDoer (%d) - Line %d"),threadID,__LINE__); sl@0: sl@0: switch(pkgDoer.iOperation) sl@0: { sl@0: case t_notification::EFileReplace: sl@0: { sl@0: RFile file; sl@0: //Generate Notification sl@0: multipleTestDoer.Printf(_L("File Replace - (%d)\n"),threadID); sl@0: r = file.Replace(fs,_path,EFileWrite); //RFile::Replace -> TFsNotification::ECreate sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: file.Close(); sl@0: sl@0: r = fs.Delete(_path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EFileCreate: sl@0: case t_notification::EFileCreate_txt_nowatch: sl@0: case t_notification::EFileCreate_txt: sl@0: case t_notification::EAllOps1: sl@0: { sl@0: multipleTestDoer.Printf(_L("MultipleNotificationTFDoer (%d) - Line %d"),threadID,__LINE__); sl@0: if(wildcard) sl@0: { sl@0: for (TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: multipleTestDoer.Printf(_L("MultipleNotificationTFDoer (%d) - Line %d"),threadID,__LINE__); sl@0: RFile file; sl@0: TBuf<40> path; sl@0: path.Append(basepath); sl@0: path.AppendNum(i); sl@0: if(pkgDoer.iOperation == t_notification::EFileCreate_txt) sl@0: { sl@0: //Create file with different extension (no notification) sl@0: path.Append(_L(".wrg")); sl@0: fs.Delete(path); sl@0: multipleTestDoer.Printf(_L("File Create (wrong extension) - %S (%d)\n"),&path,threadID); sl@0: r = file.Create(fs, path, EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: //Change path to contain file with correct extension (notification occurs) sl@0: path.Replace(path.Length()-3,3,_L("txt")); sl@0: } sl@0: else if(pkgDoer.iOperation == t_notification::EFileCreate_txt_nowatch) sl@0: { sl@0: path.Append(_L(".txt")); sl@0: } sl@0: fs.Delete(path); sl@0: sl@0: multipleTestDoer.Printf(_L("File Create - %S (%d)\n"),&path,threadID); sl@0: r = file.Create(fs, path, EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: file.Close(); sl@0: r = fs.Delete(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: multipleTestDoer.Printf(_L("MultipleNotificationTFDoer (%d) - Line %d"),threadID,__LINE__); sl@0: for(TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: multipleTestDoer.Printf(_L("MultipleNotificationTFDoer (%d) - Line %d"),threadID,__LINE__); sl@0: RFile file; sl@0: multipleTestDoer.Printf(_L("File Create - %S (%d)\n"),&_path,threadID); sl@0: r = file.Create(fs,_path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: file.Close(); sl@0: r = fs.Delete(_path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: case t_notification::EFileCreate_subs: sl@0: case t_notification::EFileCreate_subs_nowatch: sl@0: { sl@0: if (wildcard) sl@0: { sl@0: for (TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: RFile file; sl@0: TBuf<40> path; sl@0: path.Append(basepath); sl@0: path.Append(_L("SubDir\\")); sl@0: r = fs.MkDirAll(path); sl@0: if(r != KErrNone && r != KErrAlreadyExists) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: path.AppendNum(i); sl@0: fs.Delete(path); sl@0: multipleTestDoer.Printf(_L("File Create - %S (%d)\n"),&path,threadID); sl@0: r = file.Create(fs, path, EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: file.Close(); sl@0: r = fs.Delete(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: case t_notification::EFileWrite: sl@0: case t_notification::EAllOps2: sl@0: { sl@0: //Works on single file sl@0: RFile file; sl@0: TBuf<40> path; sl@0: path.Append(basepath); sl@0: path.Append(pkgDoer.iFileName); sl@0: path.Append(pkgDoer.iString); sl@0: r = file.Replace(fs,path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: for(TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: multipleTestDoer.Printf(_L("File Write - %S (%d)\n"),&path,threadID); sl@0: r = file.Write(4*i,_L8("abcd")); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: //If cache is enabled, a notification is received only when the cache is flushed sl@0: //We flush the file to make this a general test sl@0: multipleTestDoer.Printf(_L("File Flush - (%d)\n"),threadID); sl@0: r = file.Flush(); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: file.Close(); sl@0: r = fs.Delete(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EFileWrite_samesize: sl@0: { sl@0: RFile file; sl@0: TBuf<40> path; sl@0: path.Append(basepath); sl@0: path.Append(pkgDoer.iFileName); sl@0: path.Append(pkgDoer.iString); sl@0: r = file.Replace(fs,path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: multipleTestDoer.Printf(_L("File Write - %S (%d)\n"),&path,threadID); sl@0: r = file.Write(0,_L8("abcd")); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: //If cache is enabled, a notification is received only when the cache is flushed sl@0: //We flush the file to make this a general test sl@0: multipleTestDoer.Printf(_L("File Flush - (%d)\n"),threadID); sl@0: r = file.Flush(); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: for(TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: TBuf<2> toWrite; sl@0: toWrite.AppendNum(i); sl@0: multipleTestDoer.Printf(_L("File Write - %S (%d)\n"),&path,threadID); sl@0: r = file.Write(0,(TDesC8&)toWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: multipleTestDoer.Printf(_L("File Flush - (%d)\n"),threadID); sl@0: r = file.Flush(); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: file.Close(); sl@0: r = fs.Delete(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EFileWrite_async: sl@0: { sl@0: RFile file; sl@0: TBuf<40> path; sl@0: path.Append(basepath); sl@0: path.Append(pkgDoer.iFileName); sl@0: path.Append(pkgDoer.iString); sl@0: r = file.Replace(fs,path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: for(TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: TRequestStatus status; sl@0: file.Write(52*i, _L8("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), status); sl@0: User::WaitForRequest(status); sl@0: multipleTestDoer.Printf(_L("File Write Async - %S (%d)\n"),&path,threadID); sl@0: TInt fileSize; sl@0: file.Size(fileSize); sl@0: multipleTestDoer.Printf(_L("File Write Async - FileSize: %d\n"),fileSize); sl@0: multipleTestDoer.Printf(_L("File Flush - (%d)\n"),threadID); sl@0: r = file.Flush(); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: file.Close(); sl@0: r = fs.Delete(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EFileSetSize: sl@0: case t_notification::EAllOps3: sl@0: { sl@0: //Works on single file sl@0: RFile file; sl@0: TBuf<40> path; sl@0: path.Append(basepath); sl@0: path.Append(pkgDoer.iFileName); sl@0: path.Append(pkgDoer.iString); sl@0: r = file.Replace(fs,path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: //Increase file size sl@0: for(TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: r = file.SetSize(4*(i+1)); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: multipleTestDoer.Printf(_L("File Set Size - %d (%d)\n"),4*(i+1),threadID); sl@0: } sl@0: sl@0: //Decrease file size sl@0: for(TInt j = pkgDoer.iIterations - 2; j >= 0; j--) sl@0: { sl@0: r = file.SetSize(4*(j+1)); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: multipleTestDoer.Printf(_L("File Set Size - %d (%d)\n"),4*(j+1),threadID); sl@0: } sl@0: sl@0: file.Close(); sl@0: r = fs.Delete(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EFsReplace: sl@0: { sl@0: TBuf<45> path; sl@0: path.Append(basepath); sl@0: path.Append(pkgDoer.iFileName); sl@0: path.Append(pkgDoer.iString); sl@0: path.AppendNum(0); sl@0: sl@0: RFile tempFile; sl@0: multipleTestDoer.Printf(_L("RFs Replace (Create temp file) - (%d)\n"),threadID); sl@0: r = tempFile.Replace(fs,_path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: tempFile.Close(); sl@0: sl@0: multipleTestDoer.Printf(_L("RFs Replace - (%d)\n"),threadID); sl@0: r = fs.Replace(_path,path); //RFs::Replace -> TFsNotification::ERename sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: r = fs.Delete(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EFsRename: sl@0: { sl@0: TBuf<45> path; sl@0: path.Append(basepath); sl@0: path.Append(pkgDoer.iFileName); sl@0: path.Append(pkgDoer.iString); sl@0: path.AppendNum(0); sl@0: sl@0: RFile file; sl@0: r = file.Replace(fs,_path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: file.Close(); sl@0: sl@0: multipleTestDoer.Printf(_L("RFs Rename - (%d)\n"),threadID); sl@0: r = fs.Rename(_path,path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: r = fs.Delete(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EFileRename: sl@0: case t_notification::EFileRename_wild: sl@0: case t_notification::EAllOps5: sl@0: { sl@0: TBuf<45> path; sl@0: path.Append(basepath); sl@0: if (!wildcard) sl@0: { sl@0: path.Append(pkgDoer.iFileName); sl@0: path.Append(pkgDoer.iString); sl@0: } sl@0: path.AppendNum(0); sl@0: sl@0: //Delete new path to ensure it does not exist sl@0: r = fs.Delete(path); sl@0: if(r != KErrNone && r != KErrNotFound && r != KErrPathNotFound) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: if (wildcard) sl@0: { sl@0: _path.Delete(_path.Length()-1,1); sl@0: _path.AppendNum(9); sl@0: } sl@0: sl@0: RFile file; sl@0: r = file.Replace(fs, _path, EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: if (wildcard) sl@0: { sl@0: for(TInt i = 1; i <= pkgDoer.iIterations; i++) sl@0: { sl@0: path.Delete(path.Length()-1,1); sl@0: path.AppendNum(i); sl@0: multipleTestDoer.Printf(_L("File Rename - %S (%d)\n"),&path,threadID); sl@0: r = file.Rename(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: multipleTestDoer.Printf(_L("File Rename - (%d)\n"),threadID); sl@0: r = file.Rename(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: sl@0: file.Close(); sl@0: r = fs.Delete(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EFsRename_dir: sl@0: { sl@0: r = fs.MkDirAll(_path); sl@0: if(r != KErrNone && r != KErrAlreadyExists) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: TBuf<45> newPath; sl@0: newPath.Copy(_path); sl@0: newPath.Delete(newPath.Length()-1,1); sl@0: newPath.AppendNum(0); sl@0: newPath.Append(KPathDelimiter); sl@0: sl@0: //Delete new path to ensure it does not exist sl@0: r = fs.RmDir(newPath); sl@0: if(r != KErrNone && r != KErrNotFound && r != KErrPathNotFound) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: multipleTestDoer.Printf(_L("RFs Rename Dir - (%d)\n"),threadID); sl@0: r = fs.Rename(_path,newPath); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EFsDelete: sl@0: { sl@0: if (wildcard) sl@0: { sl@0: for(TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: //Create/replace file sl@0: RFile file; sl@0: TBuf<40> path; sl@0: path.Append(basepath); sl@0: r = fs.MkDirAll(path); sl@0: if(r != KErrNone && r != KErrAlreadyExists) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: path.AppendNum(i); sl@0: path.Append(_L(".txt")); sl@0: r = file.Replace(fs,path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: file.Close(); sl@0: sl@0: //Delete file sl@0: multipleTestDoer.Printf(_L("RFs Delete - %S (%d)\n"),&path,threadID); sl@0: r = fs.Delete(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: //Create file with a different extension which should not produce notifications sl@0: path.AppendNum(i); sl@0: r = file.Replace(fs,path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: file.Close(); sl@0: sl@0: //Delete that file sl@0: multipleTestDoer.Printf(_L("RFs Delete - %S (%d)\n"),&path,threadID); sl@0: r = fs.Delete(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: RFile file; sl@0: r = file.Replace(fs,_path,EFileWrite); //Make sure file exists sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: file.Close(); sl@0: sl@0: multipleTestDoer.Printf(_L("RFs Delete - (%d)\n"),threadID); sl@0: r = fs.Delete(_path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: break; sl@0: } sl@0: case t_notification::EFileSet: sl@0: { sl@0: RFile file; sl@0: r = file.Replace(fs,_path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: multipleTestDoer.Printf(_L("File Set - (%d)\n"),threadID); sl@0: r = file.Set(TTime(0),KEntryAttHidden,KEntryAttReadOnly); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: file.Close(); sl@0: break; sl@0: } sl@0: case t_notification::EFileSetAtt: sl@0: case t_notification::EAllOps4: sl@0: { sl@0: RFile file; sl@0: r = file.Replace(fs,_path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: multipleTestDoer.Printf(_L("File SetAtt - (%d)\n"),threadID); sl@0: r = file.SetAtt(KEntryAttHidden,KEntryAttReadOnly); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: file.Close(); sl@0: r = fs.Delete(_path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EFileSetAtt_subs: sl@0: { sl@0: if (wildcard) sl@0: { sl@0: TBuf<40> path; sl@0: path.Append(basepath); sl@0: path.Append(_L("SubDir\\")); sl@0: r = fs.MkDirAll(path); sl@0: if(r != KErrNone && r != KErrAlreadyExists) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: //Create/replace files and set their attributes sl@0: for(TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: RFile file; sl@0: TBuf<40> dirPath; sl@0: dirPath.Append(path); sl@0: dirPath.AppendNum(i); sl@0: dirPath.Append(_L(".ext")); sl@0: r = file.Replace(fs, dirPath, EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: multipleTestDoer.Printf(_L("File SetAtt Subs - %d.ext - (%d)\n"),i,threadID); sl@0: r = file.SetAtt(KEntryAttHidden,KEntryAttReadOnly); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: file.Close(); sl@0: r = fs.Delete(dirPath); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: } sl@0: break; sl@0: } sl@0: case t_notification::EFsSetEntry: sl@0: { sl@0: RFile file; sl@0: r = file.Replace(fs,_path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: file.Close(); sl@0: sl@0: multipleTestDoer.Printf(_L("RFs SetEntry - (%d)\n"),threadID); sl@0: r = fs.SetEntry(_path,TTime(0),KEntryAttHidden,KEntryAttReadOnly); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EDismount: sl@0: { sl@0: multipleTestDoer.Printf(_L("DismountFileSystem - (%d)\n"),threadID); sl@0: r = fs.DismountFileSystem(pkgDoer.iFileName,globalDriveNum); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EMount: sl@0: { sl@0: multipleTestDoer.Printf(_L("MountFileSystem - (%d)\n"),threadID); sl@0: r = fs.MountFileSystem(pkgDoer.iFileName,globalDriveNum); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EMountScan: sl@0: { sl@0: multipleTestDoer.Printf(_L("DismountFileSystem - (%d)\n"),threadID); sl@0: r = fs.DismountFileSystem(pkgDoer.iFileName,globalDriveNum); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: TBool isMount; sl@0: multipleTestDoer.Printf(_L("MountFileSystemAndScan - (%d)\n"),threadID); sl@0: r = fs.MountFileSystemAndScan(pkgDoer.iFileName,globalDriveNum,isMount); sl@0: if(!isMount) sl@0: safe_test(multipleTestDoer,KErrGeneral,__LINE__,pkgDoer.iLineCall); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EMountDismount: sl@0: { sl@0: for(TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: multipleTestDoer.Printf(_L("DismountFileSystem - (%d)\n"),threadID); sl@0: r = fs.DismountFileSystem(pkgDoer.iFileName,globalDriveNum); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: multipleTestDoer.Printf(_L("MountFileSystem - (%d)\n"),threadID); sl@0: r = fs.MountFileSystem(pkgDoer.iFileName,globalDriveNum); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: break; sl@0: } sl@0: case t_notification::EFormat: sl@0: { sl@0: RFormat format; sl@0: TInt count = -1; sl@0: TBuf<2> driveDes; sl@0: driveDes.Append(pkgDoer.iFileName); sl@0: driveDes.Append((TChar)':'); sl@0: format.Open(fs,driveDes,EQuickFormat,count); sl@0: multipleTestDoer.Printf(_L("Format - (%d)\n"),threadID); sl@0: while(count != 0) sl@0: { sl@0: format.Next(count); sl@0: } sl@0: format.Close(); sl@0: sl@0: break; sl@0: } sl@0: case t_notification::EMediaCardRemoval: sl@0: case t_notification::EMediaCardInsertion: sl@0: { sl@0: //These are MANUAL tests, they require the removal/insertion of the media card sl@0: //Instructions are given out in the watcher thread sl@0: break; sl@0: } sl@0: case t_notification::ESetDriveName: sl@0: { sl@0: for(TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: multipleTestDoer.Printf(_L("SetDriveName - MyDrive\n")); sl@0: _LIT(KDriveName,"MyDrive"); sl@0: r = fs.SetDriveName(globalDriveNum,KDriveName); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: multipleTestDoer.Printf(_L("SetDriveName - MyDrive2\n")); sl@0: _LIT(KDriveName2,"MyDrive2"); sl@0: r = fs.SetDriveName(globalDriveNum,KDriveName2); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: break; sl@0: } sl@0: case t_notification::ERawDiskWrite: sl@0: { sl@0: RRawDisk rawdisk; sl@0: TInt drive = 0; sl@0: TBuf<1> driveDes; sl@0: driveDes.Append(pkgDoer.iFileName); sl@0: RFs::CharToDrive(pkgDoer.iFileName[0],drive); sl@0: r = rawdisk.Open(fs,drive); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: //Read some data sl@0: TBuf8<10> readData; sl@0: r = rawdisk.Read(0,readData); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: //Write it back sl@0: TPtrC8 dataPtr(readData); sl@0: r = rawdisk.Write((TInt64)0,dataPtr); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: rawdisk.Close(); sl@0: break; sl@0: } sl@0: case t_notification::ESetVolumeLabel: sl@0: { sl@0: for(TInt i = 0; i < pkgDoer.iIterations; i++) sl@0: { sl@0: multipleTestDoer.Printf(_L("SetVolumeLabel - MyVolume\n")); sl@0: _LIT(KVolumeLabel,"MyVolume"); sl@0: r = fs.SetVolumeLabel(KVolumeLabel,globalDriveNum); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: multipleTestDoer.Printf(_L("SetVolumeLabel - MyVolume2\n")); sl@0: _LIT(KVolumeLabel2,"MyVolume2"); sl@0: r = fs.SetVolumeLabel(KVolumeLabel2,globalDriveNum); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: } sl@0: break; sl@0: } sl@0: case t_notification::EFsRmDir: sl@0: { sl@0: r = fs.MkDirAll(_path); //Make sure directory exists sl@0: if(r != KErrNone && r != KErrAlreadyExists) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: multipleTestDoer.Printf(_L("RFs RmDir - Remove directory\n")); sl@0: r = fs.RmDir(_path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::EFsRmDir_wild: sl@0: { sl@0: if (wildcard) sl@0: { sl@0: TBuf<40> path; sl@0: path.Append(basepath); sl@0: path.Append(_L("SubDir\\")); sl@0: r = fs.MkDirAll(path); sl@0: if(r != KErrNone && r != KErrAlreadyExists) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: multipleTestDoer.Printf(_L("RFs RmDir - Remove directory\n")); sl@0: r = fs.RmDir(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: } sl@0: case t_notification::EFsRmDir_nonEmpty: sl@0: case t_notification::EFsMkDir: sl@0: { sl@0: TBuf<50> path; sl@0: path.Append(_path); sl@0: path.Append(pkgDoer.iFileName); //Append another sub-directory sl@0: multipleTestDoer.Printf(_L("RFs RmDir \n")); sl@0: r=fs.RmDir(path); sl@0: if(r != KErrNone && r != KErrPathNotFound && r != KErrNotFound) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: r=fs.RmDir(_path); sl@0: if(r != KErrNone && r != KErrPathNotFound && r != KErrNotFound) sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: multipleTestDoer.Printf(_L("RFs MkDir \n")); sl@0: r=fs.MkDir(path); sl@0: multipleTestDoer (r==KErrPathNotFound); sl@0: r=fs.MkDir(_path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: r=fs.MkDir(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: multipleTestDoer.Printf(_L("RFs RmDir nonEmpty - Full path: %S"),&_path); sl@0: r = fs.RmDir(_path); sl@0: if(r != KErrInUse) sl@0: safe_test(multipleTestDoer,KErrGeneral,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: r = fs.RmDir(path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: multipleTestDoer.Printf(_L("RFs EFsRmDir_nonEmpty - Full path: %S"),&_path); sl@0: r = fs.RmDir(_path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: break; sl@0: } sl@0: case t_notification::EAllOps6: sl@0: { sl@0: //Set drive name to TestDrive sl@0: multipleTestDoer.Printf(_L("SetDriveName - TestDrive\n")); sl@0: _LIT(KDriveName,"TestDrive"); sl@0: r = fs.SetDriveName(globalDriveNum,KDriveName); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: //Set volume label to TestVolume sl@0: multipleTestDoer.Printf(_L("SetVolumeLabel - TestVolume\n")); sl@0: _LIT(KVolumeLabel,"TestVolume"); sl@0: r = fs.SetVolumeLabel(KVolumeLabel,globalDriveNum); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: break; sl@0: } sl@0: case t_notification::ECFileManMove: sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: sl@0: multipleTestDoer.Printf(_L("Doer - ECFileManMove_part1\n")); sl@0: sl@0: //Stage 1 - Create File & write some data sl@0: RFile file; sl@0: r = file.Replace(fs,_path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: r = file.SetSize(4); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: file.Close(); sl@0: sl@0: CFileMan* cfman = NULL; sl@0: TRAP(r, cfman = CFileMan::NewL(fs);) sl@0: test(r == KErrNone); sl@0: test(cfman != NULL); sl@0: TBuf<40> unmonitored_path; sl@0: unmonitored_path.Append(gDriveToTest); sl@0: unmonitored_path.Append(_L(":\\F32-TST\\")); sl@0: unmonitored_path.Append(pkgDoer.iString); sl@0: sl@0: //Stage 2 - Move to unmonitored Dir sl@0: //Rename 1 sl@0: r = cfman->Move(_path,unmonitored_path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: //SetSize (size := 8) sl@0: RFile file2; sl@0: r = file2.Open(fs,unmonitored_path,EFileWrite); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: r = file2.SetSize(8); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: file2.Flush(); sl@0: file2.Close(); sl@0: sl@0: //Stage 3 - Move back to monitored Dir sl@0: //Rename 2 sl@0: r = cfman->Move(unmonitored_path,_path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: //Stage 4 - Delete sl@0: //Delete sl@0: r = cfman->Delete(_path); sl@0: safe_test(multipleTestDoer,r,__LINE__,pkgDoer.iLineCall); sl@0: sl@0: delete cleanup; sl@0: delete cfman; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: break; sl@0: } sl@0: } sl@0: sl@0: fs.Close(); sl@0: multipleTestDoer.End(); sl@0: multipleTestDoer.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * Test process Capabilites tries to set up filters on the sl@0: * the private folder for uid 01234567. sl@0: * This function returns the results to trying to add filters on the specified path. sl@0: * sl@0: * There are three MMP files: sl@0: * t_notifier_nocaps.mmp, t_notifier_allfiles.mmp, t_notifier_belongs.mmp sl@0: * sl@0: * t_notifier_nocaps.mmp - sl@0: * This process does not have any capabilites, so should not be allowed to set the filter. sl@0: * t_notifier_allfiles.mmp - sl@0: * This process has ALLFILES capability, so should sl@0: * t_notifier_belongs.mmp - sl@0: * This process is process with UID 01234567 so this should work too. sl@0: * sl@0: * See: f32test\server\t_notifier_caps.cpp sl@0: */ sl@0: TInt TestProcessCapabilities(const TDesC& aProcessName) sl@0: { sl@0: RProcess process; sl@0: TUidType uid; sl@0: TPtrC command((TText*)&gDriveToTest,1); sl@0: TInt r = process.Create(aProcessName,command,uid); sl@0: test(r==KErrNone); sl@0: process.Resume(); sl@0: TRequestStatus s1; sl@0: TRequestStatus s2; sl@0: RTimer tim; sl@0: r = tim.CreateLocal(); sl@0: test(r==KErrNone); sl@0: TTimeIntervalMicroSeconds32 delay = 5000000; //5 seconds sl@0: tim.After(s1,delay); sl@0: process.Logon(s2); sl@0: User::WaitForRequest(s1,s2); sl@0: test(s2.Int()!=KRequestPending); sl@0: r = process.ExitReason(); sl@0: process.Close(); sl@0: return r; sl@0: } sl@0: sl@0: /* sl@0: * Creates a file and writes to it twice. sl@0: * Used in TestTwoNotificationsL(). sl@0: */ sl@0: TInt TwoNotificationsTFDoer(TAny* aAny) sl@0: { sl@0: RTest testDoer(_L("TestTwoNotificationsThreadFunctionDoer")); sl@0: testDoer.Start(_L("TestTwoNotificationsThreadFunctionDoer")); sl@0: sl@0: SThreadPackageMultiple package = *(SThreadPackageMultiple*)aAny; sl@0: TBuf<40> path; sl@0: path.Append(gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); //len=22 sl@0: path.Append(package.iFileName); sl@0: sl@0: //Delete file so we definitely get a create notification sl@0: RFs fs; sl@0: TInt r = fs.Connect(); sl@0: testDoer(r==KErrNone); sl@0: r = fs.Delete(path); sl@0: testDoer(r==KErrNone || r==KErrPathNotFound || r==KErrNotFound); sl@0: r = fs.MkDirAll(path); sl@0: testDoer(r==KErrNone || r==KErrAlreadyExists); sl@0: sl@0: testDoer.Printf(_L("TestTwoNotificationsThreadFunctionDoer - Create File %S\n"),&path); sl@0: //Create file sl@0: RFile file; sl@0: r = file.Create(fs,path,EFileWrite); sl@0: testDoer(r == KErrNone); sl@0: sl@0: testDoer.Printf(_L("TestTwoNotificationsThreadFunctionDoer - Size File 1 %S\n"),&path); sl@0: TInt fileSize = 0; sl@0: r = file.Size(fileSize); sl@0: testDoer(r == KErrNone); sl@0: testDoer(fileSize==0); sl@0: sl@0: testDoer.Printf(_L("TestTwoNotificationsThreadFunctionDoer - Write File 1 %S\n"),&path); sl@0: r = file.Write(_L8("1234")); sl@0: testDoer(r == KErrNone); sl@0: testDoer.Printf(_L("TestTwoNotificationsThreadFunctionDoer - Size File 2 %S\n"),&path); sl@0: r = file.Size(fileSize); sl@0: testDoer(r == KErrNone); sl@0: test(fileSize==4); sl@0: sl@0: testDoer.Printf(_L("TestTwoNotificationsThreadFunctionDoer - Write File 2 %S\n"),&path); sl@0: r = file.Write(_L8("5678")); sl@0: testDoer(r == KErrNone); sl@0: testDoer.Printf(_L("TestTwoNotificationsThreadFunctionDoer - Size File 3 %S\n"),&path); sl@0: r = file.Size(fileSize); sl@0: testDoer(r == KErrNone); sl@0: test(fileSize==8); sl@0: sl@0: file.Close(); sl@0: sl@0: fs.Close(); sl@0: testDoer.End(); sl@0: testDoer.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * The following enum are for the CFileMan test sl@0: */ sl@0: enum TCFsManEnum sl@0: { sl@0: ECFManCreate1 = 0x01, sl@0: ECFManWrite1 = 0x02, sl@0: ECFManDelete1 = 0x04, sl@0: ECFManCreate2 = 0x08, sl@0: ECFManSetSize1 = 0x10, sl@0: ECFManWrite2 = 0x20, sl@0: ECFManAtt1 = 0x40, sl@0: ECFManDelete2 = 0x80, sl@0: //Either a create, copy, delete (above - not supported in test) sl@0: //or rename operation (below) sl@0: ECFManRename1 = 0x100, sl@0: ECFManRename2 = 0x200 sl@0: }; sl@0: sl@0: /* sl@0: * Used by MultipleNotificationsTFWatcher() to test the notifications. sl@0: */ sl@0: void HandleMultipleNotifications(RTest& aTest, SThreadPackageMultiple& aPackage, CFsNotify* notify, TDesC& aFullname) sl@0: { sl@0: RThread thread; sl@0: TUint64 threadID = thread.Id().Id(); sl@0: TInt numNotifications = 0; sl@0: TInt64 fileSize = 0; sl@0: TBool overflow = EFalse; sl@0: sl@0: TInt scratch = 0; sl@0: sl@0: for(TInt i = 0; i < aPackage.iMaxNotifications; ) //Outer-loop to control when we should exit sl@0: { sl@0: aTest.Printf(_L("(%d) - NextNotification\n"),threadID); sl@0: const TFsNotification* notification = notify->NextNotification(); sl@0: while(notification != NULL) sl@0: { sl@0: numNotifications++; sl@0: aTest.Printf(_L("NumNotifications = %d\n"),numNotifications); sl@0: //Test notification is not null. sl@0: //We should be getting 1 notification. sl@0: aTest(notification != NULL); sl@0: sl@0: aTest.Printf(_L("(%d) - Notification Type\n"),threadID); sl@0: TFsNotification::TFsNotificationType notificationType = notification->NotificationType(); sl@0: aTest(notificationType & aPackage.iNotifyType || sl@0: notificationType & TFsNotification::EOverflow); sl@0: sl@0: aTest.Printf(_L("Notification Type = %u - (%d)\n"),notificationType,threadID); sl@0: sl@0: if(notificationType != TFsNotification::EOverflow) sl@0: { sl@0: aTest.Printf(_L("(%d) - Notification Path\n"),threadID); sl@0: TPtrC _pathC; sl@0: ((TFsNotification*) notification)->Path(_pathC); sl@0: aTest.Printf(_L("%S - (%d)\n"),&_pathC,threadID); sl@0: sl@0: if(aPackage.iOperation == t_notification::ECFileManMove sl@0: && (scratch == (ECFManWrite1 | ECFManCreate1))) sl@0: { sl@0: TChar drive = gDriveToTest; sl@0: TBuf<40> unmodified_path; sl@0: unmodified_path.Append(drive); sl@0: unmodified_path.Append(_L(":\\F32-TST\\")); sl@0: unmodified_path.Append(_L("cf1le.man")); sl@0: ((TFsNotification*) notification)->NewName(_pathC); sl@0: TInt matches = _pathC.Match(unmodified_path); sl@0: safe_test(aTest,matches,__LINE__,aPackage.iLineCall); sl@0: } sl@0: else if((scratch == (ECFManWrite1 | ECFManCreate1 | ECFManRename1))) sl@0: { sl@0: ((TFsNotification*) notification)->NewName(_pathC); sl@0: safe_test(aTest,_pathC.Match(aFullname),__LINE__,aPackage.iLineCall); sl@0: } sl@0: else sl@0: { sl@0: safe_test(aTest,_pathC.Match(aFullname),__LINE__,aPackage.iLineCall); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: aTest.Printf(_L("(%d) - OVERFLOW\n"),threadID); sl@0: //Overflow sl@0: overflow = ETrue; sl@0: return; sl@0: } sl@0: sl@0: //notificationType will only be of 1 type sl@0: if(notificationType == TFsNotification::EFileChange) sl@0: { sl@0: if(!(((aPackage.iNotifyType & TFsNotification::EFileChange) == TFsNotification::EFileChange) && sl@0: (aPackage.iOperation == t_notification::EFileWrite || sl@0: aPackage.iOperation == t_notification::EFileWrite_async || sl@0: aPackage.iOperation == t_notification::EFileWrite_samesize || sl@0: aPackage.iOperation == t_notification::EFileSetSize || sl@0: aPackage.iOperation == t_notification::ECFileManMove || sl@0: aPackage.iOperation == t_notification::EAllOps2 || sl@0: aPackage.iOperation == t_notification::EAllOps3))) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: sl@0: if (aPackage.iOperation == t_notification::ECFileManMove) sl@0: { sl@0: ((TFsNotification*) notification)->FileSize(fileSize); sl@0: //File just been created and written to. sl@0: if(fileSize == 4) sl@0: { sl@0: scratch |= ECFManWrite1; sl@0: } sl@0: else if(fileSize == 8) sl@0: { sl@0: scratch |= ECFManWrite2; sl@0: } sl@0: } sl@0: else if (aPackage.iNotifyType == TFsNotification::EFileChange) sl@0: { sl@0: ((TFsNotification*) notification)->FileSize(fileSize); sl@0: aTest.Printf(_L("Filesize - %d (%d)\n"),fileSize,threadID); sl@0: //A notification is received every time the size is changed sl@0: //due to the flushing sl@0: if (aPackage.iOperation == t_notification::EFileWrite_async) sl@0: { sl@0: //We write 52 letters sl@0: if(fileSize != 52*(i+1)) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: } sl@0: else if (aPackage.iOperation == t_notification::EFileWrite_samesize) sl@0: { sl@0: //Only 4 letters in file sl@0: if(fileSize != 4) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: } sl@0: else if (i < aPackage.iIterations) sl@0: { sl@0: //We write/increase size by 4 letters/bytes sl@0: if(fileSize != 4*(i+1)) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: } sl@0: else sl@0: { sl@0: //We decrease size by 4 bytes sl@0: if(fileSize != 4*(aPackage.iMaxNotifications-i)) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: } sl@0: } sl@0: } sl@0: else if(notificationType == TFsNotification::ECreate) sl@0: { sl@0: if(!(((aPackage.iNotifyType & TFsNotification::ECreate) == TFsNotification::ECreate) && sl@0: (aPackage.iOperation == t_notification::EFileCreate || sl@0: aPackage.iOperation == t_notification::EFileReplace || sl@0: aPackage.iOperation == t_notification::EFileCreate_subs || sl@0: aPackage.iOperation == t_notification::EFileCreate_subs_nowatch || sl@0: aPackage.iOperation == t_notification::EFileCreate_txt_nowatch || sl@0: aPackage.iOperation == t_notification::EFileCreate_txt || sl@0: aPackage.iOperation == t_notification::EFsMkDir || sl@0: aPackage.iOperation == t_notification::ECFileManMove || sl@0: aPackage.iOperation == t_notification::EAllOps1 || sl@0: aPackage.iOperation == t_notification::EAllOps2 || sl@0: aPackage.iOperation == t_notification::EAllOps3 || sl@0: aPackage.iOperation == t_notification::EAllOps4 || sl@0: aPackage.iOperation == t_notification::EAllOps5))) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: if (aPackage.iOperation == t_notification::EFileCreate_txt) sl@0: { sl@0: //Check filename is of correct extension sl@0: TPtrC _path; sl@0: ((TFsNotification*) notification)->Path(_path); sl@0: TBuf<5> _ext; sl@0: _ext.Append(_L(".txt")); sl@0: TBuf<5> ext; sl@0: ext.Append(_path.Right(4)); sl@0: safe_test(aTest,ext.Match(_ext),__LINE__,aPackage.iLineCall); sl@0: } sl@0: else if (aPackage.iOperation == t_notification::ECFileManMove) sl@0: { sl@0: if(scratch & ECFManCreate1) sl@0: { sl@0: scratch |= ECFManCreate2; //File created second time sl@0: } sl@0: else sl@0: { sl@0: scratch |= ECFManCreate1; //File created first time sl@0: } sl@0: } sl@0: } sl@0: else if(notificationType == TFsNotification::EDelete) sl@0: { sl@0: if(!(((aPackage.iNotifyType & TFsNotification::EDelete) == TFsNotification::EDelete) && sl@0: (aPackage.iOperation == t_notification::EFsDelete || sl@0: aPackage.iOperation == t_notification::EFsRmDir || sl@0: aPackage.iOperation == t_notification::EFsRmDir_nonEmpty || sl@0: aPackage.iOperation == t_notification::EFsRmDir_wild || sl@0: aPackage.iOperation == t_notification::ECFileManMove || sl@0: aPackage.iOperation == t_notification::EAllOps1 || sl@0: aPackage.iOperation == t_notification::EAllOps2 || sl@0: aPackage.iOperation == t_notification::EAllOps3 || sl@0: aPackage.iOperation == t_notification::EAllOps4))) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: sl@0: if(aPackage.iOperation == t_notification::ECFileManMove) sl@0: { sl@0: if(scratch & ECFManDelete1) sl@0: { sl@0: scratch |= ECFManDelete2; sl@0: } sl@0: else sl@0: { sl@0: scratch |= ECFManDelete1; sl@0: } sl@0: } sl@0: } sl@0: else if(notificationType == TFsNotification::ERename) sl@0: { sl@0: if(!(((aPackage.iNotifyType & TFsNotification::ERename) == TFsNotification::ERename) && sl@0: (aPackage.iOperation == t_notification::EFileRename || sl@0: aPackage.iOperation == t_notification::EFileRename_wild || sl@0: aPackage.iOperation == t_notification::EFsReplace || sl@0: aPackage.iOperation == t_notification::ECFileManMove || sl@0: aPackage.iOperation == t_notification::EFsRename || sl@0: aPackage.iOperation == t_notification::EFsRename_dir || sl@0: aPackage.iOperation == t_notification::EAllOps5))) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: TPtrC newnameC; sl@0: ((TFsNotification*)notification)->NewName(newnameC); sl@0: aTest.Printf(_L("%S - (%d)\n"),&newnameC,threadID); sl@0: sl@0: TPtrC _pathC; sl@0: ((TFsNotification*) notification)->Path(_pathC); sl@0: sl@0: TBuf<40> _path; sl@0: _path.Copy(_pathC); sl@0: sl@0: if (aPackage.iOperation == t_notification::EFsRename_dir) sl@0: { sl@0: _path.Delete(_path.Length()-1,1); sl@0: _path.AppendNum(0); sl@0: _path.Append(KPathDelimiter); sl@0: } sl@0: else if (aPackage.iOperation == t_notification::EFileRename_wild) sl@0: { sl@0: _path.Delete(_path.Length()-1,1); sl@0: _path.AppendNum(numNotifications); sl@0: } sl@0: else sl@0: { sl@0: _path.AppendNum(0); sl@0: } sl@0: sl@0: if(aPackage.iOperation != t_notification::ECFileManMove) sl@0: { sl@0: safe_test(aTest,newnameC.Match(_path),__LINE__,aPackage.iLineCall); sl@0: } sl@0: else if(scratch & ECFManRename1) sl@0: { sl@0: scratch |= ECFManRename2; sl@0: } sl@0: else sl@0: { sl@0: scratch |= ECFManRename1; sl@0: } sl@0: sl@0: } sl@0: else if(notificationType == TFsNotification::EAttribute) sl@0: { sl@0: if(!(((aPackage.iNotifyType & TFsNotification::EAttribute) == TFsNotification::EAttribute) && sl@0: (aPackage.iOperation == t_notification::EFsSetEntry || sl@0: aPackage.iOperation == t_notification::EFileSet || sl@0: aPackage.iOperation == t_notification::EFileSetAtt || sl@0: aPackage.iOperation == t_notification::EFileSetAtt_subs || sl@0: aPackage.iOperation == t_notification::ECFileManMove || sl@0: aPackage.iOperation == t_notification::EAllOps4))) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: TUint setAtt = 0; sl@0: TUint clearAtt = 0; sl@0: ((TFsNotification*) notification)->Attributes(setAtt, clearAtt); sl@0: sl@0: if(aPackage.iOperation == t_notification::ECFileManMove) sl@0: { sl@0: scratch |= ECFManAtt1; sl@0: } sl@0: else sl@0: { sl@0: if(setAtt != KEntryAttHidden) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: if(clearAtt != KEntryAttReadOnly) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: } sl@0: } sl@0: else if(notificationType == TFsNotification::EMediaChange) sl@0: { sl@0: if(!(((aPackage.iNotifyType & TFsNotification::EMediaChange) == TFsNotification::EMediaChange) && sl@0: (aPackage.iOperation == t_notification::EMount || sl@0: aPackage.iOperation == t_notification::EMountScan || sl@0: aPackage.iOperation == t_notification::EDismount || sl@0: aPackage.iOperation == t_notification::EMountDismount || sl@0: aPackage.iOperation == t_notification::EMediaCardInsertion || sl@0: aPackage.iOperation == t_notification::EMediaCardRemoval || sl@0: aPackage.iOperation == t_notification::EFormat || sl@0: aPackage.iOperation == t_notification::ECFileManMove || sl@0: aPackage.iOperation == t_notification::ERawDiskWrite))) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: } sl@0: else if(notificationType == TFsNotification::EDriveName) sl@0: { sl@0: if(!(((aPackage.iNotifyType & TFsNotification::EDriveName) == TFsNotification::EDriveName) && sl@0: (aPackage.iOperation == t_notification::ESetDriveName || sl@0: aPackage.iOperation == t_notification::EAllOps6))) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: } sl@0: else if(notificationType == TFsNotification::EVolumeName) sl@0: { sl@0: if(!(((aPackage.iNotifyType & TFsNotification::EVolumeName) == TFsNotification::EVolumeName) && sl@0: (aPackage.iOperation == t_notification::ESetVolumeLabel || sl@0: aPackage.iOperation == t_notification::EAllOps6))) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: sl@0: TPtrC newnameC; sl@0: ((TFsNotification*)notification)->NewName(newnameC); sl@0: aTest.Printf(_L("New volume name: %S - (%d)\n"),&newnameC,threadID); sl@0: } sl@0: sl@0: i++; sl@0: notification = notify->NextNotification(); sl@0: if (notification == NULL) sl@0: aTest.Printf(_L("Notification is NULL - (%d)\n"),threadID); sl@0: } sl@0: sl@0: if(i==1) //First iteration will only ever get 1 notification sl@0: { sl@0: if(numNotifications != 1) sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: } sl@0: sl@0: if(numNotifications < aPackage.iMaxNotifications && !overflow) //Ensure we get all of the notifications we expected sl@0: { sl@0: TRequestStatus status; sl@0: notify->RequestNotifications(status); sl@0: User::WaitForRequest(status); sl@0: } sl@0: } sl@0: sl@0: //0x307 = create1 | write1 | delete1 | rename1 | rename2 sl@0: if(aPackage.iOperation == t_notification::ECFileManMove && (scratch != 0x307)) sl@0: { sl@0: aTest.Printf(_L("CFileManMove test failure - scratch = 0x%x"),scratch); sl@0: safe_test(aTest,KErrGeneral,__LINE__,aPackage.iLineCall); sl@0: } sl@0: sl@0: } sl@0: sl@0: /* sl@0: * Watches for changes in files/directories. sl@0: * Used in TestMultipleNotificationsL(). sl@0: */ sl@0: TInt MultipleNotificationsTFWatcher(TAny* aAny) sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: sl@0: RThread thread; sl@0: TUint64 threadID = thread.Id().Id(); sl@0: sl@0: SThreadPackageMultiple package = *(SThreadPackageMultiple*) aAny; sl@0: RTest multipleWatcherTest(_L("MultipleNotificationsTFWatcher")); sl@0: multipleWatcherTest.Start(_L("MultipleNotificationsTFWatcher")); sl@0: sl@0: RFs fs; sl@0: fs.Connect(); sl@0: sl@0: multipleWatcherTest.Printf(_L("MultipleNotificationsTFWatcher (%d) - Create CFsNotify\n"),threadID); sl@0: CFsNotify* notify = NULL; sl@0: TRAPD(r,notify = CFsNotify::NewL(fs,package.iBufferSize)); sl@0: safe_test(multipleWatcherTest,r,__LINE__,package.iLineCall); sl@0: TBuf<40> path; sl@0: TBuf<20> filename; sl@0: if(package.iNotifyType != TFsNotification::EMediaChange && sl@0: package.iNotifyType != TFsNotification::EDriveName && sl@0: package.iNotifyType != TFsNotification::EVolumeName && sl@0: package.iOperation != t_notification::EAllOps6) sl@0: { sl@0: path.Append(gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); //len=22 sl@0: path.Append(package.iFileName); sl@0: filename.Append(package.iString); sl@0: } sl@0: else sl@0: { sl@0: path.Append((TChar)globalDriveNum+(TChar)'A'); sl@0: path.Append(_L(":")); sl@0: } sl@0: TBuf<40> fullname; sl@0: fullname.Append(path); sl@0: fullname.Append(filename); sl@0: sl@0: if (package.iNotifyType == TFsNotification::EVolumeName || sl@0: package.iOperation == t_notification::EAllOps6) sl@0: { sl@0: //Ensure volume has no label sl@0: multipleWatcherTest.Printf(_L("Set volume label to nothing\n")); sl@0: r = fs.SetVolumeLabel(_L(""),globalDriveNum); sl@0: safe_test(multipleWatcherTest,r,__LINE__,package.iLineCall); sl@0: } sl@0: sl@0: if (package.iNotifyType == TFsNotification::EDriveName || sl@0: package.iOperation == t_notification::EAllOps6) sl@0: { sl@0: //Ensure drive has no name sl@0: multipleWatcherTest.Printf(_L("Set drive name to nothing\n")); sl@0: r = fs.SetDriveName(globalDriveNum,_L("")); sl@0: safe_test(multipleWatcherTest,r,__LINE__,package.iLineCall); sl@0: } sl@0: sl@0: multipleWatcherTest.Printf(_L("MultipleNotificationsTFWatcher - Add Notification for path %S\n"),&path); sl@0: multipleWatcherTest.Printf(_L("Add Notification for type %u - (%d)\n"),(TUint)package.iNotifyType,threadID); sl@0: r = notify->AddNotification((TUint)package.iNotifyType,path,filename); sl@0: safe_test(multipleWatcherTest,r,__LINE__,package.iLineCall); sl@0: sl@0: TRequestStatus status; sl@0: multipleWatcherTest.Printf(_L("(%d) - Request Notifications\n"),threadID); sl@0: r = notify->RequestNotifications(status); sl@0: safe_test(multipleWatcherTest,r,__LINE__,package.iLineCall); sl@0: sl@0: if (package.iOperation == t_notification::EMediaCardRemoval) sl@0: { sl@0: multipleWatcherTest.Printf(_L("*****************************************************************\n")); sl@0: multipleWatcherTest.Printf(_L("Waiting 10 seconds.\n")); sl@0: multipleWatcherTest.Printf(_L("This is a MANUAL test, it requires the removal of the media card.\n")); sl@0: multipleWatcherTest.Printf(_L("PLEASE REMOVE THE MEDIA CARD. (DriveNumber %d)\n"),globalDriveNum); sl@0: multipleWatcherTest.Printf(_L("Or press Ctrl + F5 on the emulator.\n")); sl@0: multipleWatcherTest.Printf(_L("*****************************************************************\n")); sl@0: } sl@0: if (package.iOperation == t_notification::EMediaCardInsertion) sl@0: { sl@0: multipleWatcherTest.Printf(_L("*******************************************************************\n")); sl@0: multipleWatcherTest.Printf(_L("Waiting 10 seconds.\n")); sl@0: multipleWatcherTest.Printf(_L("This is a MANUAL test, it requires the insertion of the media card.\n")); sl@0: multipleWatcherTest.Printf(_L("PLEASE INSERT THE MEDIA CARD. (DriveNumber %d)\n"),globalDriveNum); sl@0: multipleWatcherTest.Printf(_L("*******************************************************************\n")); sl@0: } sl@0: sl@0: multipleWatcherTest.Printf(_L("(%d) - Signal Test thread to start Doer thread\n"),threadID); sl@0: package.iBarrier.Signal(); sl@0: User::WaitForRequest(status); sl@0: sl@0: multipleWatcherTest.Printf(_L("(%d) - MultipleNotificationsTFWatcher Line %d\n"),threadID,__LINE__); sl@0: sl@0: //Handles the notifications sl@0: HandleMultipleNotifications(multipleWatcherTest, package, notify, (TDesC&)fullname); sl@0: sl@0: multipleWatcherTest.Printf(_L("(%d) - MultipleNotificationsTFWatcher Line %d\n"),threadID,__LINE__); sl@0: sl@0: delete notify; sl@0: fs.Close(); sl@0: multipleWatcherTest.End(); sl@0: multipleWatcherTest.Close(); sl@0: delete cleanup; sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * TestTwoNotificationsL - Tests File Write, 1 Doer writes to a file twice. sl@0: * 1 Watcher watches for file write changes. Just so happens that the second one overflows. sl@0: */ sl@0: TInt TestTwoNotificationsL() sl@0: { sl@0: test.Next(_L("TestTwoNotifications")); sl@0: sl@0: RFs fs; sl@0: fs.Connect(); sl@0: RSemaphore twoNotificationsDoerBar; sl@0: SThreadPackageMultiple package; sl@0: _LIT(KFileName,"file0.write"); sl@0: package.iIterations = 10; sl@0: package.iOperation = t_notification::EFileWrite; sl@0: package.iNotifyType = TFsNotification::EFileChange; sl@0: package.iFileName = KFileName; sl@0: package.iBufferSize = 100; //Should get changed to KMin... in CFsNotify::NewL sl@0: sl@0: User::LeaveIfError(twoNotificationsDoerBar.CreateLocal(0)); sl@0: User::LeaveIfError(package.iBarrier.CreateLocal(0)); sl@0: RThread watcher; sl@0: RThread doer; sl@0: sl@0: TInt r = watcher.Create(_L("TestTwoNotificationsWatcherThread"),MultipleNotificationsTFWatcher,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&package); sl@0: test(r==KErrNone); sl@0: r = doer.Create(_L("TestTwoNotificationsDoerThread"),TwoNotificationsTFDoer,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&package); sl@0: test(r==KErrNone); sl@0: test.Next(_L("TestTwoNotifications - Resume Watcher")); sl@0: watcher.Resume(); sl@0: test.Next(_L("TestTwoNotifications - Wait for Watcher to be ready")); sl@0: package.iBarrier.Wait(); //Wait till Watcher has requested notification sl@0: test.Next(_L("TestTwoNotifications - Resume Doer")); sl@0: doer.Resume(); sl@0: sl@0: test.Next(_L("TestTwoNotifications - Wait for doer thread death")); sl@0: TRequestStatus status; sl@0: doer.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(doer.ExitReason()==KErrNone); sl@0: sl@0: test.Next(_L("TestTwoNotifications - Wait for watcher thread death")); sl@0: watcher.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(watcher.ExitReason()==KErrNone); sl@0: sl@0: CLOSE_AND_WAIT(doer); sl@0: CLOSE_AND_WAIT(watcher); sl@0: sl@0: twoNotificationsDoerBar.Close(); sl@0: package.iBarrier.Close(); sl@0: fs.Close(); sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: /* sl@0: * Watch two threads to receive two notifications. sl@0: * Used in TestTwoDoersL(). sl@0: */ sl@0: TInt TestTwoDoersWatcher(TAny* aAny) sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: sl@0: RSemaphore& twoThreadsBarrier = *(RSemaphore*)aAny; sl@0: RTest twoThreadsWatcherTest(_L("TwoThreadsWatcher")); sl@0: twoThreadsWatcherTest.Start(_L("TwoThreadsWatcher")); sl@0: sl@0: RFs fs; sl@0: fs.Connect(); sl@0: sl@0: twoThreadsWatcherTest.Next(_L("Create CFsNotify")); sl@0: CFsNotify* notify = NULL; sl@0: TRAPD(r,notify = CFsNotify::NewL(fs,200)); sl@0: twoThreadsWatcherTest(r == KErrNone); sl@0: sl@0: TBuf<40> path1; sl@0: TBuf<20> filename1; sl@0: TBuf<40> path2; sl@0: TBuf<20> filename2; sl@0: path1.Append(gDriveToTest); sl@0: path2.Append(gDriveToTest); sl@0: path1.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: filename1.Append(_L("file1.create")); sl@0: path2.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: filename2.Append(_L("file2.create")); sl@0: TBuf<40> fullname1; sl@0: fullname1.Append(path1); sl@0: fullname1.Append(filename1); sl@0: TBuf<40> fullname2; sl@0: fullname2.Append(path2); sl@0: fullname2.Append(filename2); sl@0: sl@0: twoThreadsWatcherTest.Printf(_L("TwoThreadsWatcher - Add Notification for %S\n"),&path1); sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,path1,filename1); sl@0: twoThreadsWatcherTest(r == KErrNone); sl@0: sl@0: twoThreadsWatcherTest.Printf(_L("TwoThreadsWatcher - Add Notification for %S\n"),&path2); sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,path2,filename2); sl@0: twoThreadsWatcherTest(r == KErrNone); sl@0: sl@0: TRequestStatus status; sl@0: twoThreadsWatcherTest.Next(_L("TwoThreadsWatcher - Request Notifications")); sl@0: r = notify->RequestNotifications(status); sl@0: twoThreadsWatcherTest(r == KErrNone); sl@0: sl@0: twoThreadsBarrier.Signal(); //Signal Doer threads to start sl@0: User::WaitForRequest(status); sl@0: sl@0: // We should be getting 2 notifications sl@0: // Test notifications are not null and check notification types and paths sl@0: // 1st notification: sl@0: twoThreadsWatcherTest.Next(_L("TwoThreadsWatcher - First Notification")); sl@0: const TFsNotification* notification = notify->NextNotification(); sl@0: twoThreadsWatcherTest(notification != NULL); sl@0: twoThreadsWatcherTest.Next(_L("TwoThreadsWatcher - First Notification Type")); sl@0: TFsNotification::TFsNotificationType notificationType = ((TFsNotification*)notification)->NotificationType(); sl@0: twoThreadsWatcherTest(notificationType == TFsNotification::ECreate); sl@0: twoThreadsWatcherTest.Next(_L("TwoThreadsWatcher - First Notification Path")); sl@0: TPtrC _pathC; sl@0: ((TFsNotification*)notification)->Path(_pathC); sl@0: twoThreadsWatcherTest.Printf(_L("TwoThreadsWatcher - First Notification Path returned %S\n"),&_pathC); sl@0: TBuf<40> _path; sl@0: _path.Copy(_pathC); sl@0: //We can't guarantee which thread ran first so check that it was either path1 or path2 sl@0: twoThreadsWatcherTest(_path.Match(fullname1) == KErrNone || _path.Match(fullname2) == KErrNone); sl@0: sl@0: // 2nd notification: sl@0: twoThreadsWatcherTest.Next(_L("TwoThreadsWatcher - Second Notification")); sl@0: notification = notify->NextNotification(); sl@0: // Check if next notification exists sl@0: if (!notification) sl@0: { sl@0: notify->RequestNotifications(status); sl@0: User::WaitForRequest(status); sl@0: notification = notify->NextNotification(); sl@0: } sl@0: twoThreadsWatcherTest(notification != NULL); sl@0: twoThreadsWatcherTest.Next(_L("TwoThreadsWatcher - Second Notification Type")); sl@0: notificationType = ((TFsNotification*)notification)->NotificationType(); sl@0: twoThreadsWatcherTest(notificationType == TFsNotification::ECreate); sl@0: twoThreadsWatcherTest.Next(_L("TwoThreadsWatcher - Second Notification Path")); sl@0: ((TFsNotification*)notification)->Path(_pathC); sl@0: twoThreadsWatcherTest.Printf(_L("TwoThreadsWatcher - Second Notification Path returned %S\n"),&_pathC); sl@0: _path.Copy(_pathC); sl@0: twoThreadsWatcherTest(_path.Match(fullname1) == KErrNone || _path.Match(fullname2) == KErrNone); sl@0: sl@0: delete notify; sl@0: fs.Close(); sl@0: twoThreadsWatcherTest.End(); sl@0: twoThreadsWatcherTest.Close(); sl@0: delete cleanup; sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * TestTwoDoersL - Two Doer threads create a file each and there's one Watcher sl@0: * which expects two notifications (one from each Doer). sl@0: */ sl@0: TInt TestTwoDoersL() sl@0: { sl@0: test.Next(_L("TestTwoDoers")); sl@0: sl@0: RFs fs; sl@0: fs.Connect(); sl@0: sl@0: _LIT(KFileName1,"file1.create"); sl@0: _LIT(KFileName2,"file2.create"); sl@0: RSemaphore simpleBarrierTest; sl@0: SThreadPackage pkgDoer1; sl@0: SThreadPackage pkgDoer2; sl@0: pkgDoer1.iFileName = KFileName1; sl@0: pkgDoer2.iFileName = KFileName2; sl@0: sl@0: User::LeaveIfError(pkgDoer1.iBarrier.CreateLocal(0)); sl@0: User::LeaveIfError(pkgDoer2.iBarrier.CreateLocal(0)); sl@0: User::LeaveIfError(simpleBarrierTest.CreateLocal(0)); sl@0: RThread watcher; sl@0: RThread doer1; sl@0: RThread doer2; sl@0: sl@0: watcher.Create(_L("TestTwoDoers-WatcherThread"),TestTwoDoersWatcher,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&simpleBarrierTest); sl@0: doer1.Create(_L("TestTwoDoers-DoerThread1"),SimpleSingleNotificationTFDoer,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&pkgDoer1); sl@0: doer2.Create(_L("TestTwoDoers-DoerThread2"),SimpleSingleNotificationTFDoer,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&pkgDoer2); sl@0: watcher.Resume(); sl@0: simpleBarrierTest.Wait(); //Wait until Watcher has created CFsNotify sl@0: sl@0: doer1.Resume(); sl@0: doer2.Resume(); sl@0: sl@0: test.Next(_L("TestTwoDoers - Wait for doer1 thread death")); sl@0: TRequestStatus status; sl@0: doer1.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(doer1.ExitReason()==KErrNone); sl@0: sl@0: test.Next(_L("TestTwoDoers - Wait for doer2 thread death")); sl@0: doer2.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(doer2.ExitReason()==KErrNone); sl@0: sl@0: test.Next(_L("TestTwoDoers - Wait for watcher thread death")); sl@0: watcher.Logon(status); sl@0: RTimer timer1; sl@0: TInt r = timer1.CreateLocal(); sl@0: safe_test(test,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: TRequestStatus timeout; sl@0: TTimeIntervalMicroSeconds32 time = 10000000; //10 seconds sl@0: timer1.After(timeout,time); sl@0: User::WaitForRequest(timeout,status); sl@0: test(status.Int() != KRequestPending); sl@0: timer1.Cancel(); sl@0: timer1.Close(); sl@0: //User::WaitForRequest(status); sl@0: test(watcher.ExitReason()==KErrNone); sl@0: sl@0: CLOSE_AND_WAIT(doer1); sl@0: CLOSE_AND_WAIT(doer2); sl@0: CLOSE_AND_WAIT(watcher); sl@0: sl@0: pkgDoer1.iBarrier.Close(); sl@0: pkgDoer2.iBarrier.Close(); sl@0: simpleBarrierTest.Close(); sl@0: fs.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * TestTwoWatchersL - Uses two watcher threads and one doer thread to test that running sl@0: * two distinct sub sessions at the same time (both watch the same file). sl@0: */ sl@0: TInt TestTwoWatchersL() sl@0: { sl@0: test.Next(_L("TestTwoWatchers")); sl@0: RFs fs; sl@0: fs.Connect(); sl@0: _LIT(KFileName,"file.creat3"); sl@0: SThreadPackage pkgDoer; sl@0: pkgDoer.iFileName = KFileName; sl@0: sl@0: SThreadPackage watcherPkg; sl@0: watcherPkg.iFileName = KFileName; sl@0: sl@0: User::LeaveIfError(pkgDoer.iBarrier.CreateLocal(0)); sl@0: User::LeaveIfError(watcherPkg.iBarrier.CreateLocal(0)); sl@0: RThread watcher; sl@0: RThread watcher2; sl@0: RThread doer; sl@0: watcher.Create(_L("TestTwoWatchersWatcherThread"),SimpleSingleNotificationTFWatcher,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&watcherPkg); sl@0: watcher2.Create(_L("TestTwoWatchersWatcher2Thread"),SimpleSingleNotificationTFWatcher,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&watcherPkg); sl@0: doer.Create(_L("TestTwoWatchersDoerThread"),SimpleSingleNotificationTFDoer,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&pkgDoer); sl@0: watcher.Resume(); sl@0: watcher2.Resume(); sl@0: watcherPkg.iBarrier.Wait(); //Wait till both watchers have requested notification sl@0: watcherPkg.iBarrier.Wait(); sl@0: doer.Resume(); sl@0: sl@0: test.Printf(_L("Wait for DOER to terminate , Line %d"),__LINE__); sl@0: TRequestStatus status; sl@0: doer.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(doer.ExitReason()==KErrNone); sl@0: sl@0: test.Printf(_L("Wait for WATCHER to terminate , Line %d"),__LINE__); sl@0: watcher.Logon(status); sl@0: RTimer timer1; sl@0: TInt r = timer1.CreateLocal(); sl@0: safe_test(test,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: TRequestStatus timeout; sl@0: TTimeIntervalMicroSeconds32 time = 10000000; //10 seconds sl@0: timer1.After(timeout,time); sl@0: User::WaitForRequest(timeout,status); sl@0: test(status.Int() != KRequestPending); sl@0: timer1.Cancel(); sl@0: timer1.Close(); sl@0: // User::WaitForRequest(status); sl@0: test(watcher.ExitReason()==KErrNone); sl@0: sl@0: test.Printf(_L("Wait for WATCHER2 to terminate , Line %d"),__LINE__); sl@0: watcher2.Logon(status); sl@0: RTimer timer2; sl@0: r = timer2.CreateLocal(); sl@0: safe_test(test,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: TRequestStatus timeout2; sl@0: timer2.After(timeout2,time); sl@0: User::WaitForRequest(timeout2,status); sl@0: test(status.Int() != KRequestPending); sl@0: timer2.Cancel(); sl@0: timer2.Close(); sl@0: //User::WaitForRequest(status); sl@0: test(watcher2.ExitReason()==KErrNone); sl@0: sl@0: CLOSE_AND_WAIT(doer); sl@0: CLOSE_AND_WAIT(watcher); sl@0: CLOSE_AND_WAIT(watcher2); sl@0: sl@0: pkgDoer.iBarrier.Close(); sl@0: watcherPkg.iBarrier.Close(); sl@0: fs.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: /* sl@0: * TestTwoWatchersTwoDoersL - Two watcher threads watches two different doer threads. sl@0: */ sl@0: TInt TestTwoWatchersTwoDoersL() sl@0: { sl@0: test.Next(_L("TestTwoWatchersTwoDoers")); sl@0: RFs fs; sl@0: fs.Connect(); sl@0: _LIT(KFileName1,"f1le.create"); sl@0: _LIT(KFileName2,"f2le.create"); sl@0: SThreadPackage package1; sl@0: package1.iFileName = KFileName1; sl@0: sl@0: SThreadPackage package2; sl@0: package2.iFileName = KFileName2; sl@0: sl@0: User::LeaveIfError(package1.iBarrier.CreateLocal(0)); sl@0: User::LeaveIfError(package2.iBarrier.CreateLocal(0)); sl@0: RThread watcher; sl@0: RThread watcher2; sl@0: RThread doer; sl@0: RThread doer2; sl@0: watcher.Create(_L("TestTwoWatchersTwoDoersWatcherThread"),SimpleSingleNotificationTFWatcher,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&package1); sl@0: doer.Create(_L("TestTwoWatchersTwoDoersDoerThread"),SimpleSingleNotificationTFDoer,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&package1); sl@0: sl@0: watcher2.Create(_L("TestTwoWatchersTwoDoersWatcher2Thread"),SimpleSingleNotificationTFWatcher,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&package2); sl@0: doer2.Create(_L("TestTwoWatchersTwoDoersDoer2Thread"),SimpleSingleNotificationTFDoer,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&package2); sl@0: watcher.Resume(); sl@0: watcher2.Resume(); sl@0: package1.iBarrier.Wait(); //Wait till both watchers have requested notification sl@0: package2.iBarrier.Wait(); sl@0: doer.Resume(); sl@0: doer2.Resume(); sl@0: sl@0: test.Printf(_L("Wait for DOER to terminate , Line %d"),__LINE__); sl@0: TRequestStatus status; sl@0: doer.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(doer.ExitReason()==KErrNone); sl@0: sl@0: test.Printf(_L("Wait for DOER2 to terminate , Line %d"),__LINE__); sl@0: doer2.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(doer2.ExitReason()==KErrNone); sl@0: sl@0: test.Printf(_L("Wait for WATCHER to terminate , Line %d"),__LINE__); sl@0: watcher.Logon(status); sl@0: RTimer timer1; sl@0: TInt r = timer1.CreateLocal(); sl@0: safe_test(test,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: TRequestStatus timeout; sl@0: TTimeIntervalMicroSeconds32 time = 10000000; //10 seconds sl@0: timer1.After(timeout,time); sl@0: User::WaitForRequest(timeout,status); sl@0: test(status.Int() != KRequestPending); sl@0: timer1.Cancel(); sl@0: timer1.Close(); sl@0: test(watcher.ExitReason()==KErrNone); sl@0: sl@0: test.Printf(_L("Wait for WATCHER2 to terminate , Line %d"),__LINE__); sl@0: watcher2.Logon(status); sl@0: RTimer timer2; sl@0: r = timer2.CreateLocal(); sl@0: safe_test(test,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: TRequestStatus timeout2; sl@0: timer2.After(timeout2,time); sl@0: User::WaitForRequest(timeout2,status); sl@0: test(status.Int() != KRequestPending); sl@0: timer2.Cancel(); sl@0: timer2.Close(); sl@0: test(watcher2.ExitReason()==KErrNone); sl@0: sl@0: CLOSE_AND_WAIT(doer); sl@0: CLOSE_AND_WAIT(doer2); sl@0: CLOSE_AND_WAIT(watcher); sl@0: CLOSE_AND_WAIT(watcher2); sl@0: sl@0: package1.iBarrier.Close(); sl@0: package2.iBarrier.Close(); sl@0: fs.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: /* sl@0: * Multi-purpose test sl@0: * sl@0: * If aFailureExpected is ETrue, it is expected that the watcher thread is not terminated normally, sl@0: * due to the notification(s) not being sent. sl@0: * Since this function is called many times, aLineCall is used to show the line where it is called from. sl@0: * See SThreadPackageMultiple. sl@0: */ sl@0: TInt TestMultipleNotificationsL(const TDesC& aFilename, const TDesC& aString, TInt aIterations, sl@0: TInt aMaxNotifications, t_notification::EOperation aOperation, sl@0: TUint aNotifyType, TInt aBufferSize, TBool aFailureExpected, TInt aLineCall) sl@0: { sl@0: test.Next(_L("TestMultipleNotifications")); sl@0: sl@0: RFs fs; sl@0: fs.Connect(); sl@0: SThreadPackageMultiple package; sl@0: package.iIterations = aIterations; sl@0: package.iMaxNotifications = aMaxNotifications; sl@0: package.iOperation = aOperation; sl@0: package.iNotifyType = (TFsNotification::TFsNotificationType)aNotifyType; sl@0: package.iString = aString; sl@0: package.iFileName = aFilename; sl@0: package.iBufferSize = aBufferSize; sl@0: package.iLineCall = aLineCall; sl@0: sl@0: User::LeaveIfError(package.iBarrier.CreateLocal(0)); sl@0: RThread watcher; sl@0: RThread doer; sl@0: RTimer tim; sl@0: User::LeaveIfError(tim.CreateLocal()); sl@0: sl@0: TInt r = watcher.Create(_L("TestMultipleNotificationsWatcherThread"),MultipleNotificationsTFWatcher,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&package); sl@0: safe_test(test,r,__LINE__,package.iLineCall); sl@0: r = doer.Create(_L("TestMultipleNotificationsDoerThread"),MultipleNotificationTFDoer,KDefaultStackSize*2,KMinHeapSize,KMaxHeapSize,&package); sl@0: safe_test(test,r,__LINE__,package.iLineCall); sl@0: test.Next(_L("TestMultipleNotifications - Resume Watcher")); sl@0: watcher.Resume(); sl@0: test.Next(_L("TestMultipleNotifications - Wait for Watcher to be ready")); sl@0: package.iBarrier.Wait(); //Wait till Watcher has requested notification sl@0: test.Next(_L("TestMultipleNotifications - Resume Doer")); sl@0: doer.Resume(); sl@0: sl@0: test.Next(_L("TestMultipleNotifications - Wait for doer thread death")); sl@0: TRequestStatus status; sl@0: doer.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test.Printf(_L("TestMultipleNotifications - Doer Exit Reason %d\n"),doer.ExitReason()); sl@0: safe_test(test,doer.ExitReason(),__LINE__,package.iLineCall); sl@0: sl@0: TRequestStatus timStatus; sl@0: TTimeIntervalMicroSeconds32 timeout; sl@0: if (aFailureExpected && !(package.iOperation == t_notification::EMediaCardInsertion || sl@0: package.iOperation == t_notification::EMediaCardRemoval)) sl@0: { sl@0: timeout = 1500000; //1.5 seconds, we don't want to wait too long if we expect it to fail sl@0: } sl@0: else sl@0: { sl@0: timeout = 10000000; //10 seconds sl@0: } sl@0: tim.After(timStatus,timeout); sl@0: sl@0: test.Next(_L("TestMultipleNotifications - Wait for watcher thread death or timeout")); sl@0: watcher.Logon(status); sl@0: User::WaitForRequest(status,timStatus); sl@0: if(!(status != KRequestPending || aFailureExpected)) sl@0: safe_test(test,KErrGeneral,__LINE__,package.iLineCall); sl@0: sl@0: test.Printf(_L("TestMultipleNotifications - Watcher Exit Reason %d\n"),watcher.ExitReason()); sl@0: safe_test(test,watcher.ExitReason(),__LINE__,package.iLineCall); sl@0: sl@0: CLOSE_AND_WAIT(doer); sl@0: sl@0: if(status == KRequestPending) sl@0: { sl@0: watcher.Kill(KErrTimedOut); sl@0: test.Printf(_L("TestMultipleNotifications - Watcher timed out\n")); sl@0: } sl@0: CLOSE_AND_WAIT(watcher); sl@0: sl@0: package.iBarrier.Close(); sl@0: fs.Close(); sl@0: tim.Close(); sl@0: test.Printf(_L("----------------------------------------------------------------------\n")); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt TestMultipleNotificationsL(const TDesC& aFilename, const TDesC& aString, TInt aIterations, sl@0: TInt aMaxNotifications, t_notification::EOperation aOperation, sl@0: TFsNotification::TFsNotificationType aNotifyType, TInt aBufferSize, sl@0: TBool aFailureExpected, TInt aLineCall) sl@0: { sl@0: return TestMultipleNotificationsL(aFilename, aString, aIterations, aMaxNotifications, aOperation, sl@0: (TUint)aNotifyType, aBufferSize, aFailureExpected, aLineCall); sl@0: } sl@0: sl@0: TInt TestMultipleNotificationsL(const TDesC& aFilename, TInt aIterations, TInt aMaxNotifications, sl@0: t_notification::EOperation aOperation, TUint aNotifyType, TInt aBufferSize, sl@0: TBool aFailureExpected, TInt aLineCall) sl@0: { sl@0: return TestMultipleNotificationsL(aFilename,_L(""), aIterations, aMaxNotifications, aOperation, aNotifyType, sl@0: aBufferSize, aFailureExpected, aLineCall); sl@0: } sl@0: sl@0: sl@0: // Watcher for TestAddRemoveNotificationL() sl@0: TInt TestAddRemoveNotificationWatcher(TAny* aAny) sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: RThread thread; sl@0: TUint64 threadId = thread.Id().Id(); sl@0: sl@0: SThreadPackage pkgDoer = *(SThreadPackage*)aAny; sl@0: RSemaphore& addRemoveBarrier = pkgDoer.iBarrier; sl@0: sl@0: RTest addRemoveWatcherTest(_L("TestAddRemoveNotificationWatcher")); sl@0: addRemoveWatcherTest.Start(_L("TestAddRemoveNotificationWatcher")); sl@0: sl@0: RFs fs; sl@0: fs.Connect(); sl@0: sl@0: addRemoveWatcherTest.Printf(_L("TestAddRemoveNotificationWatcher(%d) - Create CFsNotify\n"),threadId); sl@0: CFsNotify* notify = NULL; sl@0: TRAPD(r,notify = CFsNotify::NewL(fs,100); ); sl@0: addRemoveWatcherTest( r == KErrNone); sl@0: TBuf<40> path; sl@0: TBuf<20> filename; sl@0: path.Append(gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); //len=22 sl@0: filename.Append(pkgDoer.iFileName); sl@0: sl@0: addRemoveWatcherTest.Printf(_L("TestAddRemoveNotificationWatcher - Add Notification for %S\n"),&path); sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,path,filename); sl@0: addRemoveWatcherTest(r==KErrNone); sl@0: addRemoveWatcherTest.Printf(_L("TestAddRemoveNotificationWatcher(%d) - Remove Notifications\n"),threadId); sl@0: r = notify->RemoveNotifications(); sl@0: addRemoveWatcherTest(r==KErrNone); sl@0: addRemoveWatcherTest.Printf(_L("TestAddRemoveNotificationWatcher(%d) - Request Notifications\n"),threadId); sl@0: TRequestStatus status; sl@0: r = notify->RequestNotifications(status); sl@0: addRemoveWatcherTest(r==KErrNone); sl@0: addRemoveWatcherTest.Printf(_L("TestAddRemoveNotificationWatcher status = %d"),status.Int()); sl@0: addRemoveBarrier.Signal(); sl@0: sl@0: addRemoveWatcherTest.Printf(_L("TestAddRemoveNotificationWatcher(%d) - NextNotification\n"),threadId); sl@0: //We should not be getting any notifications as the notification request has been removed sl@0: const TFsNotification* notification = notify->NextNotification(); sl@0: addRemoveWatcherTest(notification == NULL); sl@0: sl@0: delete notify; sl@0: fs.Close(); sl@0: addRemoveWatcherTest.End(); sl@0: addRemoveWatcherTest.Close(); sl@0: delete cleanup; sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: /* sl@0: * TestAddRemoveNotificationL - Watcher adds and removes notification request. sl@0: * Any changes by doer thread should not be detected. sl@0: */ sl@0: TInt TestAddRemoveNotificationL() sl@0: { sl@0: test.Next(_L("TestAddRemoveNotification")); sl@0: RFs fs; sl@0: fs.Connect(); sl@0: sl@0: SThreadPackage package; sl@0: _LIT(KFileName,"noFile.create"); sl@0: package.iFileName = KFileName; sl@0: sl@0: User::LeaveIfError(package.iBarrier.CreateLocal(0)); sl@0: RThread watcher; sl@0: RThread doer; sl@0: sl@0: watcher.Create(_L("TestAddRemoveNotification-WatcherThread"),TestAddRemoveNotificationWatcher,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&package); sl@0: doer.Create(_L("TestAddRemoveNotification-DoerThread"),SimpleSingleNotificationTFDoer,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&package); sl@0: watcher.Resume(); sl@0: sl@0: test.Printf(_L("TestAddRemoveNotification - Wait until Watcher has created CFsNotify\n")); sl@0: package.iBarrier.Wait(); //Wait until Watcher has created CFsNotify sl@0: doer.Resume(); sl@0: sl@0: test.Next(_L("TestAddRemoveNotification - Wait for doer thread death")); sl@0: TRequestStatus status; sl@0: doer.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(doer.ExitReason()==KErrNone); sl@0: sl@0: test.Next(_L("TestAddRemoveNotification - Wait for watcher thread death")); sl@0: watcher.Logon(status); sl@0: RTimer timer1; sl@0: TInt r = timer1.CreateLocal(); sl@0: safe_test(test,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: TRequestStatus timeout; sl@0: TTimeIntervalMicroSeconds32 time = 10000000; //10 seconds sl@0: timer1.After(timeout,time); sl@0: User::WaitForRequest(timeout,status); sl@0: test(status.Int() != KRequestPending); sl@0: timer1.Cancel(); sl@0: timer1.Close(); sl@0: test.Printf(_L("Test - Watcher Exit Reason %d\n"),watcher.ExitReason()); sl@0: test(watcher.ExitReason()==KErrNone); sl@0: sl@0: CLOSE_AND_WAIT(doer); sl@0: CLOSE_AND_WAIT(watcher); sl@0: sl@0: package.iBarrier.Close(); sl@0: fs.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: /* sl@0: * Adds and cancels notification request. sl@0: * Used in TestCancelNotificationL(). sl@0: */ sl@0: TInt TestCancelNotificationWatcher(TAny* aAny) sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: sl@0: RTest cancelNotificationsWatcherTest(_L("TestCancelNotificationWatcher")); sl@0: cancelNotificationsWatcherTest.Start(_L("TestCancelNotificationWatcher")); sl@0: sl@0: RThread thread; sl@0: TUint64 threadId = thread.Id().Id(); sl@0: sl@0: SThreadPackageDualSemaphore pkgDoer = *(SThreadPackageDualSemaphore*)aAny; sl@0: RSemaphore& addRemoveBarrier = pkgDoer.iBarrier; sl@0: RSemaphore& addRemoveBarrier2 = pkgDoer.iBarrier2; sl@0: sl@0: RFs fs; sl@0: fs.Connect(); sl@0: sl@0: cancelNotificationsWatcherTest.Printf(_L("TestCancelNotificationWatcher(%d) - Create CFsNotify\n"),threadId); sl@0: CFsNotify* notify = NULL; sl@0: TRAPD(r,notify = CFsNotify::NewL(fs,100); ); sl@0: cancelNotificationsWatcherTest(r == KErrNone); sl@0: TBuf<40> path; sl@0: TBuf<20> filename; sl@0: path.Append(gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); //len=22 sl@0: filename.Append(pkgDoer.iFileName); sl@0: sl@0: cancelNotificationsWatcherTest.Printf(_L("TestCancelNotificationWatcher - Add Notification for %S\n"),&path); sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,path,filename); sl@0: cancelNotificationsWatcherTest(r==KErrNone); sl@0: cancelNotificationsWatcherTest.Printf(_L("TestCancelNotificationWatcher(%d) - Request Notifications\n"),threadId); sl@0: TRequestStatus status; sl@0: r = notify->RequestNotifications(status); sl@0: cancelNotificationsWatcherTest(r==KErrNone); sl@0: sl@0: cancelNotificationsWatcherTest.Printf(_L("TestCancelNotificationWatcher(%d) - Cancel Notifications\n"),threadId); sl@0: r = notify->CancelNotifications(status); sl@0: cancelNotificationsWatcherTest(r==KErrNone); sl@0: sl@0: cancelNotificationsWatcherTest.Printf(_L("TestCancelNotificationWatcher(%d) - Signal W1 - Start doer\n"),threadId); sl@0: addRemoveBarrier.Signal(); //W1 - Start doer sl@0: sl@0: cancelNotificationsWatcherTest.Printf(_L("TestCancelNotificationWatcher(%d) - Wait S1 - doer complete\n"),threadId); sl@0: addRemoveBarrier2.Wait(); //S1 - Wait for doer to have created file sl@0: sl@0: cancelNotificationsWatcherTest.Printf(_L("TestCancelNotificationWatcher(%d) - NextNotification\n"),threadId); sl@0: //We should not be getting any notifications as the notification request has been removed sl@0: const TFsNotification* notification = notify->NextNotification(); sl@0: cancelNotificationsWatcherTest(notification == NULL); sl@0: sl@0: delete notify; sl@0: fs.Close(); sl@0: cancelNotificationsWatcherTest.Printf(_L("TestCancelNotificationWatcher(%d) - Complete\n"),threadId); sl@0: cancelNotificationsWatcherTest.End(); sl@0: cancelNotificationsWatcherTest.Close(); sl@0: delete cleanup; sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: /* sl@0: * TestCancelNotificationL - Watcher adds and cancels notification request. sl@0: */ sl@0: TInt TestCancelNotificationL() sl@0: { sl@0: test.Next(_L("TestCancelNotification")); sl@0: RFs fs; sl@0: fs.Connect(); sl@0: sl@0: SThreadPackageDualSemaphore package; sl@0: _LIT(KFileName,"cancel.create"); sl@0: package.iFileName = KFileName; sl@0: sl@0: User::LeaveIfError(package.iBarrier.CreateLocal(0)); sl@0: User::LeaveIfError(package.iBarrier2.CreateLocal(0)); sl@0: RThread watcher; sl@0: RThread doer; sl@0: sl@0: TInt r = watcher.Create(_L("TestCancelNotification-WatcherThread"),TestCancelNotificationWatcher,KDefaultStackSize*2,KMinHeapSize,KMaxHeapSize,&package); sl@0: test(r == KErrNone); sl@0: r = doer.Create(_L("TestCancelNotification-DoerThread"),SimpleSingleNotificationTFDoer,KDefaultStackSize*2,KMinHeapSize,KMaxHeapSize,&package); sl@0: test(r == KErrNone); sl@0: test.Printf(_L("TestCancelNotificationL - Watcher.Resume()")); sl@0: watcher.Resume(); sl@0: test.Printf(_L("TestCancelNotificationL - Waiting on package.iBarrier.Wait()")); sl@0: package.iBarrier.Wait(); //W1 - Wait until Watcher has created CFsNotify sl@0: test.Printf(_L("TestCancelNotificationL -Doer Resume")); sl@0: TRequestStatus status; sl@0: doer.Logon(status); sl@0: doer.Resume(); sl@0: sl@0: test.Next(_L("TestCancelNotification - Wait for doer thread death")); sl@0: User::WaitForRequest(status); sl@0: test(doer.ExitReason()==KErrNone); sl@0: sl@0: package.iBarrier2.Signal(); //S1 sl@0: sl@0: test.Next(_L("TestCancelNotification - Wait for watcher thread death")); sl@0: watcher.Logon(status); sl@0: sl@0: RTimer tim; sl@0: r = tim.CreateLocal(); sl@0: test(r==KErrNone); sl@0: sl@0: TRequestStatus timStatus; sl@0: TTimeIntervalMicroSeconds32 time = 10000000; //10 seconds sl@0: tim.After(timStatus,time); sl@0: sl@0: User::WaitForRequest(status,timStatus); sl@0: test(status!=KRequestPending); sl@0: test(watcher.ExitReason()==KErrNone); sl@0: sl@0: CLOSE_AND_WAIT(doer); sl@0: CLOSE_AND_WAIT(watcher); sl@0: sl@0: package.iBarrier.Close(); sl@0: package.iBarrier2.Close(); sl@0: fs.Close(); sl@0: tim.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * Test that if we close the session sl@0: * before closing the subsession (deleting CFsNotify) sl@0: * that everything is A-Ok. sl@0: */ sl@0: TInt TestSessionCloseTF(TAny* aTestCase) sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: sl@0: TRAPD(r, sl@0: RFs fs; sl@0: fs.Connect(); sl@0: RDebug::Printf("TestSessionClose\n"); sl@0: sl@0: SThreadPackage2 package = *(SThreadPackage2*)aTestCase; sl@0: package.iBarrier.Signal(); sl@0: sl@0: switch(package.iTestCase) sl@0: { sl@0: case 1: sl@0: { sl@0: RDebug::Printf("TestSessionCloseTF - Case 1 - NewL\n"); sl@0: CFsNotify* notify = CFsNotify::NewL(fs,KMinNotificationBufferSize); sl@0: User::LeaveIfNull(notify); sl@0: sl@0: RDebug::Printf("TestSessionCloseTF - Case 1 - Fs.Close\n"); sl@0: fs.Close(); sl@0: sl@0: TBuf<45> path; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: sl@0: TBuf<20> filename; sl@0: filename.Append(_L("session.close")); sl@0: sl@0: CleanupStack::PushL(notify); sl@0: sl@0: RDebug::Printf("TestSessionCloseTF - Case 1 - Add Notification - Panic Expected\n"); sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,path,filename); sl@0: User::LeaveIfError(r); sl@0: sl@0: RDebug::Printf("TestSessionCloseTF - Case 1 - After Session Close\n"); sl@0: fs.Close(); sl@0: CleanupStack::Pop(notify); sl@0: sl@0: RDebug::Printf("TestSessionCloseTF - Case 1 - After Delete Notify\n"); sl@0: delete notify; sl@0: break; sl@0: } sl@0: case 2: sl@0: { sl@0: RDebug::Printf("TestSessionCloseTF - Case 2 - NewL\n"); sl@0: CFsNotify* notify = CFsNotify::NewL(fs,KMinNotificationBufferSize); sl@0: User::LeaveIfNull(notify); sl@0: sl@0: TBuf<45> path; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: TBuf<20> filename; sl@0: filename.Append(_L("session.close")); sl@0: sl@0: RDebug::Printf("TestSessionCloseTF - Case 2 - Add Notification\n"); sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,path,filename); sl@0: test(r==KErrNone); sl@0: sl@0: RDebug::Printf("TestSessionCloseTF - Case 2 - Fs.Close\n"); sl@0: fs.Close(); sl@0: sl@0: CleanupStack::PushL(notify); sl@0: TRequestStatus status; sl@0: RDebug::Printf("TestSessionCloseTF - Case 2 - Request Notification - Panic Expected\n"); sl@0: r = notify->RequestNotifications(status); sl@0: CleanupStack::Pop(notify); sl@0: sl@0: RDebug::Printf("TestSessionCloseTF - Case 2 - After Delete Notify\n"); sl@0: delete notify; sl@0: break; sl@0: } sl@0: default: sl@0: { sl@0: break; sl@0: } sl@0: } sl@0: ); sl@0: delete cleanup; sl@0: return r; sl@0: } sl@0: sl@0: /* sl@0: * Test that if we close the session sl@0: * before closing the subsession (deleting CFsNotify) sl@0: * that everything is A-Ok. sl@0: */ sl@0: void TestSessionClose(TInt aTestCase) sl@0: { sl@0: RSemaphore sem; sl@0: User::LeaveIfError(sem.CreateLocal(0)); sl@0: sl@0: SThreadPackage2 package; sl@0: package.iTestCase = aTestCase; sl@0: package.iBarrier = sem; sl@0: sl@0: RThread thread; sl@0: thread.Create(_L("TestSessionClose"),TestSessionCloseTF,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&package); sl@0: sl@0: thread.Resume(); sl@0: sem.Wait(); sl@0: sl@0: TRequestStatus status; sl@0: thread.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test.Printf(_L("Kern-Exec 0 is EXPECTED\n")); sl@0: TInt err = thread.ExitReason(); sl@0: test(err == KErrNone); sl@0: TExitType et = thread.ExitType(); sl@0: test(et == EExitPanic); sl@0: CLOSE_AND_WAIT(thread); sl@0: sem.Close(); sl@0: } sl@0: sl@0: const TInt KNotificationOverflowIterationLimit = 7; sl@0: sl@0: /* sl@0: * Does stuff for TestOverflowL sl@0: * Synchronises such that watchers have seen 1 change. sl@0: * Then fills their buffers up to KNotificationOverflowIterationLimit. sl@0: * sl@0: */ sl@0: TInt TestOverflowDoerTF(TAny* aAny) sl@0: { sl@0: RFs fs; sl@0: fs.Connect(); sl@0: sl@0: SThreadPackage& package = *(SThreadPackage*) aAny; sl@0: sl@0: TBuf<45> path; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: path.Append(package.iFileName); sl@0: sl@0: fs.MkDirAll(path); sl@0: sl@0: RFile file; sl@0: TInt r = file.Replace(fs,path,EFileWrite); sl@0: User::LeaveIfError(r); sl@0: sl@0: //Perform first set size. sl@0: r = file.SetSize(1); sl@0: User::LeaveIfError(r); sl@0: sl@0: //Wait until both watchers have received this change. sl@0: package.iBarrier.Wait(); sl@0: sl@0: for(TInt i = 0; i< KNotificationOverflowIterationLimit; i++) sl@0: { sl@0: file.SetSize(i); sl@0: } sl@0: sl@0: file.Close(); sl@0: fs.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * Thread function used as part of TestOverflowL sl@0: * Counts the number of notifications and ensures it the correct number before overflow is received# sl@0: */ sl@0: TInt TestOverflowWatcher1TF(TAny* aAny) sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: sl@0: RTest overflowTest(_L("TestOverflowWatcher1TF")); sl@0: overflowTest.Start(_L("TestOverflowWatcher1TF")); sl@0: sl@0: SThreadPackage& package = *(SThreadPackage*) aAny; sl@0: RFs fs; sl@0: fs.Connect(); sl@0: TBuf<45> path; sl@0: TBuf<20> filename; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: filename.Append(package.iFileName); sl@0: sl@0: TRequestStatus status; sl@0: CFsNotify* notify = NULL; sl@0: sl@0: //This notification's size is 80. sl@0: //80*7 = 560. sl@0: // -4 means we should get 6 notifications sl@0: //Except the first one will still be in the buffer sl@0: // (as we've not called RequestNotification yet) so we'll only actually get 5. sl@0: TRAPD(r, notify = CFsNotify::NewL(fs,(80*7)-4)); sl@0: test(r == KErrNone); sl@0: User::LeaveIfNull(notify); sl@0: notify->AddNotification(TFsNotification::EFileChange,path,filename); sl@0: notify->RequestNotifications(status); sl@0: sl@0: //Signal that we are ready for doer to start (W1) sl@0: package.iBarrier.Signal(); sl@0: sl@0: //We wait for the 1 notification (doer only does 1 at first) sl@0: User::WaitForRequest(status); sl@0: sl@0: overflowTest.Next(_L("Overflow- Get First Notification (Start framework)")); sl@0: const TFsNotification *notification = notify->NextNotification(); sl@0: sl@0: TFsNotification::TFsNotificationType type = notification->NotificationType(); sl@0: overflowTest.Printf(_L("Overflow - First Notification Type = %d\n"),type); sl@0: sl@0: //Signal the test thread (W2) sl@0: package.iBarrier.Signal(); sl@0: //Wait for Signal to continue (W3); sl@0: package.iBarrier.Wait(); sl@0: sl@0: notify->RequestNotifications(status); sl@0: User::WaitForRequest(status); sl@0: sl@0: TInt count = 0; sl@0: overflowTest.Next(_L("Overflow- Get the rest of the notifications")); sl@0: notification = notify->NextNotification(); sl@0: while(notification != NULL) sl@0: { sl@0: sl@0: type = notification->NotificationType(); sl@0: overflowTest.Printf(_L("Overflow - NotificationType = %d\n"),type); sl@0: if(type & TFsNotification::EOverflow) sl@0: { sl@0: delete notify; sl@0: fs.Close(); sl@0: overflowTest.Printf(_L("Overflow +- Count = %d\n"),count); sl@0: overflowTest.End(); sl@0: overflowTest.Close(); sl@0: return count; sl@0: } sl@0: sl@0: notification = notify->NextNotification(); sl@0: count++; sl@0: } sl@0: overflowTest.Printf(_L("Overflow -- Count = %d\n"),count); sl@0: sl@0: overflowTest.End(); sl@0: overflowTest.Close(); sl@0: delete notify; sl@0: delete cleanup; sl@0: fs.Close(); sl@0: return -1; sl@0: } sl@0: sl@0: sl@0: /* sl@0: * Overflow test sl@0: * As some of the tests above assume sucess if they receive an overflow sl@0: * we need to ensure that overflow works properly! sl@0: */ sl@0: TInt TestOverflowL() sl@0: { sl@0: /* sl@0: * The scheme used is as follows: sl@0: * 1 Doer thread which is setting the size of a file, over and over. sl@0: * 1 watcher thread. sl@0: * sl@0: * The doer thread does 1 operation then waits on a signal. sl@0: * The watcher thread requests notification and receives 1 notification. sl@0: * It then signals the Doer thread. sl@0: * sl@0: * The doer thread continues doing setsize until the number of notifications sl@0: * should have overflowed. sl@0: * sl@0: * The watcher Waits for a signal from doer (that all of the notifications have been sent). sl@0: * The watcher's last notification should be an overflow sl@0: */ sl@0: test.Next(_L("TestOverflow")); sl@0: RFs fs; sl@0: TInt r = fs.Connect(); sl@0: test(r == KErrNone); sl@0: _LIT(KFileName,"over.flow"); sl@0: SThreadPackage doerPkg; sl@0: doerPkg.iFileName = KFileName; sl@0: sl@0: SThreadPackage watcher1Pkg; sl@0: watcher1Pkg.iFileName = KFileName; sl@0: sl@0: User::LeaveIfError(doerPkg.iBarrier.CreateLocal(0)); sl@0: User::LeaveIfError(watcher1Pkg.iBarrier.CreateLocal(0)); sl@0: RThread watcher1; sl@0: RThread doer; sl@0: watcher1.Create(_L("TestOverflowWatcher1Thread"),TestOverflowWatcher1TF,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&watcher1Pkg); sl@0: doer.Create(_L("TestOverflowDoerThread"),TestOverflowDoerTF,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&doerPkg); sl@0: watcher1.Resume(); sl@0: sl@0: //Wait until Request has been requested. (W1) sl@0: watcher1Pkg.iBarrier.Wait(); sl@0: sl@0: doer.Resume(); sl@0: sl@0: //Wait till watcher has received first notification (W2) sl@0: watcher1Pkg.iBarrier.Wait(); sl@0: sl@0: //Signal the doer that it is free to continue sl@0: //doing the rest of the operations sl@0: doerPkg.iBarrier.Signal(); sl@0: sl@0: test.Next(_L("TestOverflow - Wait for doer thread death")); sl@0: TRequestStatus status; sl@0: doer.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(doer.ExitReason()==KErrNone); sl@0: CLOSE_AND_WAIT(doer); sl@0: sl@0: //Wait until doer has finished doing notifications sl@0: //thus the watcher should receive an overflow sl@0: // (W3) sl@0: watcher1Pkg.iBarrier.Signal(); sl@0: sl@0: RTimer tim; sl@0: r = tim.CreateLocal(); sl@0: test(r==KErrNone); sl@0: TRequestStatus timStatus; sl@0: sl@0: test.Next(_L("TestOverflow - Wait for watcher1 thread death")); sl@0: TTimeIntervalMicroSeconds32 interval = 10000000; //10 seconds sl@0: tim.After(timStatus,interval); sl@0: watcher1.Logon(status); sl@0: User::WaitForRequest(status,timStatus); sl@0: test(status != KRequestPending); sl@0: /* sl@0: * The number of notifications returned here should be 5. sl@0: * This is because : sl@0: * sl@0: * The first notification means that the buffer has lost 80 (the size of this sl@0: * particular notification). Even though the client has read it becase they've not called sl@0: * RequestNotification the server doesn't know that yet so that's why it's 5 not 6. sl@0: * sl@0: * That leaves 556 - 80. Which means only 5 notifications will fit. sl@0: */ sl@0: TInt count = watcher1.ExitReason(); sl@0: test(count==5); sl@0: sl@0: CLOSE_AND_WAIT(watcher1); sl@0: watcher1Pkg.iBarrier.Close(); sl@0: doerPkg.iBarrier.Close(); sl@0: fs.Close(); sl@0: tim.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * Does stuff for TestPostOverflowL sl@0: * Synchronises such that watchers have seen 1 change. sl@0: * Then fills their buffers up to KNotificationOverflowIterationLimit. sl@0: * Then continues to request changes and akes sure that it gets 3 non-overflow notifications sl@0: * For DEF140387. sl@0: */ sl@0: TInt TestPostOverflowDoerTF(TAny* aAny) sl@0: { sl@0: RFs fs; sl@0: fs.Connect(); sl@0: sl@0: SThreadPackage& package = *(SThreadPackage*) aAny; sl@0: sl@0: TBuf<45> path; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: path.Append(package.iFileName); sl@0: sl@0: fs.MkDirAll(path); sl@0: sl@0: RFile file; sl@0: TInt r = file.Replace(fs,path,EFileWrite); sl@0: User::LeaveIfError(r); sl@0: sl@0: //Perform first set size. sl@0: r = file.SetSize(1); sl@0: User::LeaveIfError(r); sl@0: sl@0: //Wait until both watchers have received this change. sl@0: //D-W-1 sl@0: package.iBarrier.Wait(); sl@0: sl@0: for(TInt i = 0; i< KNotificationOverflowIterationLimit; i++) sl@0: { sl@0: file.SetSize(i); sl@0: } sl@0: sl@0: file.Close(); sl@0: fs.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt HandlePostOverflow(SThreadPackage& aPackage, CFsNotify* aNotify) sl@0: { sl@0: TRequestStatus status; sl@0: TInt r = aNotify->RequestNotifications(status); sl@0: test(r == KErrNone); sl@0: //Signal that overflow has been found (W4) sl@0: aPackage.iBarrier.Signal(); sl@0: sl@0: User::WaitForRequest(status); sl@0: sl@0: const TFsNotification* notification = NULL; sl@0: TInt count = 1; sl@0: sl@0: notification = aNotify->NextNotification(); sl@0: test(notification != NULL); sl@0: sl@0: //3 set sizes will be done (Sx) sl@0: aPackage.iBarrier.Wait(); sl@0: sl@0: while(count < 3) sl@0: { sl@0: TUint type = notification->NotificationType(); sl@0: if(type & TFsNotification::EOverflow) sl@0: { sl@0: return KErrOverflow; sl@0: } sl@0: notification = aNotify->NextNotification(); sl@0: if(notification == NULL) sl@0: { sl@0: r = aNotify->RequestNotifications(status); sl@0: test(r == KErrNone); sl@0: User::WaitForRequest(status); sl@0: notification = aNotify->NextNotification(); sl@0: } sl@0: test(notification != NULL); sl@0: count++; sl@0: } sl@0: return count; sl@0: } sl@0: sl@0: sl@0: /* sl@0: * Thread function used as part of TestOverflowL sl@0: * Counts the number of notifications and ensures it the correct number before overflow is received# sl@0: */ sl@0: TInt TestPostOverflowWatcher1TF(TAny* aAny) sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: sl@0: RTest overflowTest(_L("TestOverflowWatcher1TF")); sl@0: overflowTest.Start(_L("TestOverflowWatcher1TF")); sl@0: sl@0: SThreadPackage& package = *(SThreadPackage*) aAny; sl@0: RFs fs; sl@0: fs.Connect(); sl@0: TBuf<45> path; sl@0: TBuf<20> filename; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: filename.Append(package.iFileName); sl@0: sl@0: TRequestStatus status; sl@0: CFsNotify* notify = NULL; sl@0: sl@0: //This notification's size is 80. sl@0: //80*7 = 560. sl@0: // -4 means we should get 6 notifications sl@0: //Except the first one will still be in the buffer sl@0: // (as we've not called RequestNotification yet) so we'll only actually get 5. sl@0: TRAPD(r, notify = CFsNotify::NewL(fs,(80*7)-4)); sl@0: test(r == KErrNone); sl@0: User::LeaveIfNull(notify); sl@0: notify->AddNotification(TFsNotification::EFileChange,path,filename); sl@0: notify->RequestNotifications(status); sl@0: sl@0: //Signal that we are ready for doer to start (W1) sl@0: package.iBarrier.Signal(); sl@0: sl@0: //We wait for the 1 notification (doer only does 1 at first) sl@0: User::WaitForRequest(status); sl@0: sl@0: overflowTest.Next(_L("Overflow- Get First Notification (Start framework)")); sl@0: const TFsNotification *notification = notify->NextNotification(); sl@0: sl@0: TFsNotification::TFsNotificationType type = notification->NotificationType(); sl@0: overflowTest.Printf(_L("Overflow - First Notification Type = %d\n"),type); sl@0: sl@0: //Signal the test thread (W2) sl@0: package.iBarrier.Signal(); sl@0: //Wait for Signal to continue (W3); sl@0: package.iBarrier.Wait(); sl@0: sl@0: notify->RequestNotifications(status); sl@0: User::WaitForRequest(status); sl@0: sl@0: TInt handlePostOverflow = 0; sl@0: TInt count = 0; sl@0: overflowTest.Next(_L("Overflow- Get the rest of the notifications")); sl@0: notification = notify->NextNotification(); sl@0: while(notification != NULL) sl@0: { sl@0: sl@0: type = notification->NotificationType(); sl@0: overflowTest.Printf(_L("Overflow - NotificationType = %d\n"),type); sl@0: if(type & TFsNotification::EOverflow) sl@0: { sl@0: overflowTest.Printf(_L("Overflow +- Count = %d\n"),count); sl@0: if(handlePostOverflow) sl@0: { sl@0: count = HandlePostOverflow(package,notify); sl@0: } sl@0: delete notify; sl@0: fs.Close(); sl@0: overflowTest.End(); sl@0: overflowTest.Close(); sl@0: return count; sl@0: } sl@0: notification = notify->NextNotification(); sl@0: count++; sl@0: sl@0: if(count==5) sl@0: handlePostOverflow = 1; sl@0: } sl@0: overflowTest.Printf(_L("Overflow -- Count = %d\n"),count); sl@0: sl@0: overflowTest.End(); sl@0: overflowTest.Close(); sl@0: delete notify; sl@0: delete cleanup; sl@0: fs.Close(); sl@0: return -1; sl@0: } sl@0: sl@0: sl@0: TInt TestPostOverflowNotifications() sl@0: { sl@0: test.Next(_L("TestPostOverflowNotifications")); sl@0: RFs fs; sl@0: TInt r = fs.Connect(); sl@0: test(r == KErrNone); sl@0: _LIT(KFileName,"post.over"); sl@0: SThreadPackage doerPkg; sl@0: doerPkg.iFileName = KFileName; sl@0: sl@0: SThreadPackage watcher1Pkg; sl@0: watcher1Pkg.iFileName = KFileName; sl@0: sl@0: User::LeaveIfError(doerPkg.iBarrier.CreateLocal(0)); sl@0: User::LeaveIfError(watcher1Pkg.iBarrier.CreateLocal(0)); sl@0: RThread watcher1; sl@0: RThread doer; sl@0: watcher1.Create(_L("TestPostOverflowWatcher1Thread"),TestPostOverflowWatcher1TF,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&watcher1Pkg); sl@0: doer.Create(_L("TestPostOverflowDoerThread"),TestPostOverflowDoerTF,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,&doerPkg); sl@0: watcher1.Resume(); sl@0: sl@0: //Wait until Request has been requested. (W1) sl@0: watcher1Pkg.iBarrier.Wait(); sl@0: sl@0: doer.Resume(); sl@0: sl@0: //Wait till watcher has received first notification (W2) sl@0: watcher1Pkg.iBarrier.Wait(); sl@0: sl@0: //Signal the doer that it is free to continue sl@0: //doing the rest of the operations (D-W-1) sl@0: doerPkg.iBarrier.Signal(); sl@0: sl@0: test.Next(_L("TestOverflow - Wait for doer thread death")); sl@0: TRequestStatus status; sl@0: doer.Logon(status); sl@0: User::WaitForRequest(status); sl@0: test(doer.ExitReason()==KErrNone); sl@0: CLOSE_AND_WAIT(doer); sl@0: sl@0: //Wait until doer has finished doing notifications sl@0: //thus the watcher should receive an overflow sl@0: // (W3) sl@0: watcher1Pkg.iBarrier.Signal(); sl@0: sl@0: sl@0: //wait for the watcher to have processed the first overflow sl@0: //and to have requested notification. sl@0: //Then we will perform some actions here sl@0: // The watcher will wait on the semaphore until we are doing sl@0: // doing all the operations we want to do sl@0: // then it should process next notification sl@0: watcher1Pkg.iBarrier.Wait(); //W4 sl@0: sl@0: TBuf<45> path; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: path.Append(watcher1Pkg.iFileName); sl@0: RFile file; sl@0: r = file.Open(fs,path,EFileWrite); sl@0: test(r==KErrNone); sl@0: sl@0: r = file.SetSize(1); sl@0: test(r==KErrNone); sl@0: r = file.SetSize(2); sl@0: test(r==KErrNone); sl@0: r = file.SetSize(3); sl@0: test(r==KErrNone); sl@0: file.Close(); sl@0: sl@0: watcher1Pkg.iBarrier.Signal(); // Signal post operations complete (Sx) sl@0: sl@0: RTimer tim; sl@0: r = tim.CreateLocal(); sl@0: test(r==KErrNone); sl@0: TRequestStatus timStatus; sl@0: sl@0: test.Next(_L("TestOverflow - Wait for watcher1 thread death")); sl@0: TTimeIntervalMicroSeconds32 interval = 10000000; //10 seconds sl@0: tim.After(timStatus,interval); sl@0: watcher1.Logon(status); sl@0: User::WaitForRequest(status,timStatus); sl@0: test(status != KRequestPending); sl@0: /* sl@0: * The number of notifications returned here should be 3. sl@0: * This is because : sl@0: * sl@0: * The first notification means that the buffer has lost 80 (the size of this sl@0: * particular notification). Even though the client has read it becase they've not called sl@0: * RequestNotification the server doesn't know that yet so that's why it's 5 not 6. sl@0: * sl@0: * That leaves 556 - 80. Which means only 5 notifications will fit. sl@0: * sl@0: * Then overflow occurs. sl@0: * sl@0: * Then count is reset and 3 more operations are performed. sl@0: */ sl@0: TInt count = watcher1.ExitReason(); sl@0: test(count==3); sl@0: sl@0: CLOSE_AND_WAIT(watcher1); sl@0: watcher1Pkg.iBarrier.Close(); sl@0: doerPkg.iBarrier.Close(); sl@0: fs.Close(); sl@0: tim.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * Call AddNotification with a file without a path nor drive sl@0: */ sl@0: void TestNonDriveFilters() sl@0: { sl@0: test.Next(_L("TestNonDriveFilters")); sl@0: RFs fs; sl@0: TInt r = fs.Connect(); sl@0: test(r==KErrNone); sl@0: sl@0: TDriveList drives; sl@0: r = fs.DriveList(drives); sl@0: test(r==KErrNone); sl@0: sl@0: CFsNotify* notify = NULL; sl@0: TRAP(r,notify= CFsNotify::NewL(fs,KMinNotificationBufferSize)); sl@0: sl@0: TBuf<20> testfile; sl@0: testfile.Append(_L("test.file")); sl@0: sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,_L(""),testfile); sl@0: test(r==KErrNone); sl@0: sl@0: TRequestStatus status; sl@0: r = notify->RequestNotifications(status); sl@0: test(r==KErrNone); sl@0: sl@0: TBuf<40> path; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: sl@0: TBuf<40> fullname; sl@0: fullname.Append(path); sl@0: fullname.Append(testfile); sl@0: sl@0: RFile file; sl@0: r = fs.MkDirAll(path); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: r = file.Replace(fs,fullname,EFileWrite); sl@0: test(r==KErrNone); sl@0: file.Close(); sl@0: sl@0: fs.Delete(fullname); sl@0: sl@0: TChar testDrive = (TChar)gDriveToTest; sl@0: testDrive.UpperCase(); sl@0: sl@0: //Also create the file on another drive; sl@0: for(TInt i = 0; i < KMaxDrives; i++) sl@0: { sl@0: TChar drive = drives[i]; sl@0: if(drive == testDrive) sl@0: continue; sl@0: sl@0: if(drive) sl@0: { sl@0: TText16 drive16 = (TText16)(i+(TChar)'A'); sl@0: fullname.operator [](0) = drive16; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: r = fs.MkDirAll(fullname); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: r = file.Replace(fs,fullname,EFileWrite); sl@0: test(r==KErrNone); sl@0: file.Close(); sl@0: sl@0: RTimer timer1; sl@0: r = timer1.CreateLocal(); sl@0: test(r == KErrNone); sl@0: TRequestStatus timeout; sl@0: TTimeIntervalMicroSeconds32 time = 10000000; //10 seconds sl@0: timer1.After(timeout,time); sl@0: User::WaitForRequest(timeout,status); sl@0: test(status.Int() != KRequestPending); sl@0: timer1.Cancel(); sl@0: timer1.Close(); sl@0: sl@0: const TFsNotification* notification = notify->NextNotification(); sl@0: test(notification != NULL); sl@0: TPtrC _path; sl@0: r = notification->Path(_path); sl@0: test(r==KErrNone); sl@0: TChar driveletter = _path[0]; sl@0: driveletter.UpperCase(); sl@0: test(driveletter == (TChar)gDriveToTest); sl@0: sl@0: if(notification = notify->NextNotification(), notification==NULL) sl@0: { sl@0: TRequestStatus status2; sl@0: r = notify->RequestNotifications(status2); sl@0: test(r==KErrNone); sl@0: sl@0: RTimer timer2; sl@0: r = timer2.CreateLocal(); sl@0: test(r == KErrNone); sl@0: TRequestStatus timeout2; sl@0: TTimeIntervalMicroSeconds32 time2 = 10000000; //10 seconds sl@0: timer2.After(timeout2,time2); sl@0: User::WaitForRequest(timeout2,status2); sl@0: test(status2.Int() != KRequestPending); sl@0: timer2.Cancel(); sl@0: timer2.Close(); sl@0: sl@0: notification = notify->NextNotification(); sl@0: } sl@0: test(notification != NULL); sl@0: r = notification->Path(_path); sl@0: test(r==KErrNone); sl@0: driveletter = _path[0]; sl@0: driveletter.UpperCase(); sl@0: test(driveletter == (TChar)'C'); sl@0: sl@0: delete notify; sl@0: fs.Close(); sl@0: } sl@0: sl@0: // Negative testing for directory without * sl@0: // We receive no notifications for files changed under the directory sl@0: void NegativeTestDirStar() sl@0: { sl@0: RFs fs; sl@0: TInt r = fs.Connect(); sl@0: test(r==KErrNone); sl@0: sl@0: CFsNotify* notify = NULL; sl@0: TRAP(r,notify= CFsNotify::NewL(fs,KMinNotificationBufferSize)); sl@0: sl@0: TBuf<40> path; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: r = fs.MkDirAll(path); sl@0: test(r == KErrNone || r == KErrAlreadyExists); sl@0: sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,path,_L("")); sl@0: test(r==KErrNone); sl@0: sl@0: TRequestStatus status; sl@0: r = notify->RequestNotifications(status); sl@0: test(r==KErrNone); sl@0: sl@0: TBuf<40> filename; sl@0: filename.Append((TChar)gDriveToTest); sl@0: filename.Append(_L(":\\F32-TST\\T_NOTIFIER\\dir.star")); sl@0: sl@0: RFile file; sl@0: r = file.Replace(fs,filename,EFileWrite); sl@0: test(r==KErrNone); sl@0: file.Close(); sl@0: sl@0: RTimer timer1; sl@0: r = timer1.CreateLocal(); sl@0: test(r == KErrNone); sl@0: TRequestStatus timeout; sl@0: TTimeIntervalMicroSeconds32 time = 2000000; //2 seconds sl@0: timer1.After(timeout,time); sl@0: User::WaitForRequest(timeout,status); sl@0: test(status.Int() == KRequestPending); sl@0: timer1.Cancel(); sl@0: timer1.Close(); sl@0: sl@0: const TFsNotification* notification = notify->NextNotification(); sl@0: test(notification == NULL); sl@0: sl@0: delete notify; sl@0: fs.Close(); sl@0: } sl@0: sl@0: /* sl@0: * Negative Testing sl@0: */ sl@0: void NegativeTests() sl@0: { sl@0: test.Next(_L("Negative Tests")); sl@0: //1 sl@0: test.Printf(_L("NegativeTests() A\n")); sl@0: RFs fs; sl@0: CFsNotify* notify = NULL; sl@0: TInt r = fs.Connect(); sl@0: test(r == KErrNone); sl@0: TRAP(r,notify = CFsNotify::NewL(fs,0)); sl@0: test(notify != NULL); sl@0: delete notify; sl@0: notify = NULL; sl@0: sl@0: //2 sl@0: test.Printf(_L("NegativeTests() B\n")); sl@0: TRAP(r,notify = CFsNotify::NewL(fs,-1)); sl@0: test(notify != NULL); sl@0: delete notify; sl@0: notify = NULL; sl@0: sl@0: test.Printf(_L("NegativeTests() C\n")); sl@0: TRAP(r,notify = CFsNotify::NewL(fs,KMaxTInt)); sl@0: test(r==KErrArgument); sl@0: test(notify==NULL); sl@0: sl@0: //3 sl@0: test.Printf(_L("NegativeTests() D\n")); sl@0: TBuf<40> path; sl@0: path.Append((TChar)gDriveToTest); sl@0: path.Append(_L(":\\F32-TST\\T_NOTIFIER\\")); sl@0: TBuf<20> filename; sl@0: filename.Append(_L("file.txt")); sl@0: TRAP(r,notify = CFsNotify::NewL(fs,KMinNotificationBufferSize)); sl@0: test(r==KErrNone); sl@0: test(notify!=NULL); sl@0: r = notify->AddNotification(0,path,filename); sl@0: test(r == KErrArgument); sl@0: sl@0: test.Printf(_L("NegativeTests() E\n")); sl@0: r = notify->AddNotification((TUint)0x8000,path,filename); //invalid value sl@0: test(r == KErrArgument); sl@0: sl@0: test.Printf(_L("NegativeTests() F\n")); sl@0: TBuf<40> invalidPath; sl@0: invalidPath.Append(_L("1:\\*")); sl@0: r = notify->AddNotification((TUint)TFsNotification::ECreate,invalidPath,filename); sl@0: test(r == KErrNotFound || r == KErrPathNotFound); sl@0: sl@0: //4 sl@0: test.Printf(_L("NegativeTests() G\n")); sl@0: TRequestStatus wrongStatus; sl@0: wrongStatus = KRequestPending; sl@0: r = notify->RequestNotifications(wrongStatus); sl@0: test(r == KErrInUse); sl@0: sl@0: test.Printf(_L("NegativeTests() H\n")); sl@0: TRequestStatus status; sl@0: r = notify->RequestNotifications(status); sl@0: test(r==KErrNone); sl@0: r = notify->CancelNotifications(wrongStatus); sl@0: test(r == KErrInUse); sl@0: sl@0: delete notify; sl@0: notify = NULL; sl@0: fs.Close(); sl@0: } sl@0: sl@0: sl@0: /* sl@0: * RPlugin devired. sl@0: * Doesn't actually do anything special. sl@0: * Can probably be deleted. sl@0: */ sl@0: class MyRPlugin : public RPlugin sl@0: { sl@0: public: sl@0: void DoRequest(TInt aReqNo,TRequestStatus& aStatus) const; sl@0: void DoRequest(TInt aReqNo,TRequestStatus& aStatus,TDes8& a1) const; sl@0: void DoRequest(TInt aReqNo,TRequestStatus& aStatus,TDes8& a1,TDes8& a2) const; sl@0: TInt DoControl(TInt aFunction) const; sl@0: TInt DoControl(TInt aFunction,TDes8& a1) const; sl@0: TInt DoControl(TInt aFunction,TDes8& a1,TDes8& a2) const; sl@0: void DoCancel(TUint aReqMask) const; sl@0: }; sl@0: sl@0: void MyRPlugin::DoRequest(TInt aReqNo,TRequestStatus& aStatus) const sl@0: { sl@0: RPlugin::DoRequest(aReqNo,aStatus); sl@0: } sl@0: void MyRPlugin::DoRequest(TInt aReqNo,TRequestStatus& aStatus,TDes8& a1) const sl@0: { sl@0: RPlugin::DoRequest(aReqNo,aStatus,a1); sl@0: } sl@0: void MyRPlugin::DoRequest(TInt aReqNo,TRequestStatus& aStatus,TDes8& a1,TDes8& a2) const sl@0: { sl@0: RPlugin::DoRequest(aReqNo,aStatus,a1,a2); sl@0: } sl@0: TInt MyRPlugin::DoControl(TInt aFunction) const sl@0: { sl@0: return RPlugin::DoControl(aFunction); sl@0: } sl@0: TInt MyRPlugin::DoControl(TInt aFunction,TDes8& a1) const sl@0: { sl@0: return RPlugin::DoControl(aFunction,a1); sl@0: } sl@0: TInt MyRPlugin::DoControl(TInt aFunction,TDes8& a1,TDes8& a2) const sl@0: { sl@0: return RPlugin::DoControl(aFunction,a1,a2); sl@0: } sl@0: void MyRPlugin::DoCancel(TUint aReqMask) const sl@0: { sl@0: RPlugin::DoCancel(aReqMask); sl@0: } sl@0: sl@0: /* sl@0: * This tests that when file server plugins perform operations that sl@0: * the framework doesn't notify about them sl@0: */ sl@0: TInt TestNotificationsWithFServPlugins() sl@0: { sl@0: TInt r = TheFs.AddPlugin(KNotifyPluginFileName); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: r = TheFs.MountPlugin(KNotifyPluginName,(TUint)gDriveToTest.GetUpperCase() - 65); sl@0: if (r == KErrNotSupported) sl@0: { sl@0: test.Printf(_L("Plugins are not supported on pagable drives.\nSkipping test.\n")); sl@0: safe_test(test,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: } sl@0: sl@0: MyRPlugin rplugin; sl@0: TPckgBuf drivePckg(gDriveToTest); sl@0: sl@0: test.Next(_L("Open RPlugin connection for NotifyPlugin")); sl@0: r = rplugin.Open(TheFs,KNotifyPos); sl@0: safe_test(test,r,__LINE__,(TText*)Expand("t_notify_plugin.cpp")); sl@0: sl@0: test.Next(_L("Send drive letter to test down to plugin")); sl@0: r = rplugin.DoControl(KPluginSetDrive,drivePckg); sl@0: safe_test(test,r,__LINE__,(TText*)Expand("t_notify_plugin.cpp")); sl@0: rplugin.Close(); sl@0: sl@0: r = SimpleCreateTestL(); sl@0: safe_test(test,r,__LINE__,(TText*)Expand("t_notifier.cpp")); sl@0: sl@0: DismountPlugin(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /* sl@0: * This test is testing the use cases sl@0: * and for negative testing of SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION sl@0: * sl@0: * Performance tests can be found in test t_notify_perf sl@0: */ sl@0: void CallTestsL() sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: sl@0: globalDriveNum = gDriveToTest - (TChar)'A'; sl@0: sl@0: PrintLine(); sl@0: test.Start(_L("T_NOTIFIER Test Start")); sl@0: TInt r = KErrNone; sl@0: sl@0: //========================================================================================= sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2443 sl@0: //! @SYMTestType CIT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc Simple Tests/User Heap Tests sl@0: //! @SYMTestStatus Implemented sl@0: //========================================================================================= sl@0: // sl@0: // 1. Create and delete many CFsNotify objects sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("CFsNotify Creation and Delete Tests")); sl@0: //Creates and Deletes 1 CFsNotify sl@0: __UHEAP_MARK; sl@0: r = TestNewDeleteCFsNotify(1); sl@0: __UHEAP_MARKEND; sl@0: test(r==KErrNone); sl@0: //Creates and Deletes 50 CFsNotifys sl@0: __UHEAP_MARK; sl@0: r = TestNewDeleteCFsNotify(50); sl@0: __UHEAP_MARKEND; sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of User Heap Tests ---------------------------------------\n")); sl@0: // sl@0: // 2. Add notification for creating a file sl@0: // Create that file sl@0: // sl@0: PrintLine(); sl@0: __UHEAP_MARK; sl@0: r = SimpleCreateTestL(); sl@0: __UHEAP_MARKEND; sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of CFsNotify Creation and Delete Tests -------------------\n")); sl@0: // sl@0: // 3. Add notification at the root of a drive sl@0: // Create a file in that drive sl@0: // sl@0: PrintLine(); sl@0: TestRootDriveNotifications(); sl@0: test.Printf(_L("------- End of RootDriveNotifications Test ---------------------------\n")); sl@0: // sl@0: // 4. Add notification for a filename without a drive sl@0: // Create that file in the current drive sl@0: // Create that file in another drive sl@0: // sl@0: PrintLine(); sl@0: TestNonDriveFilters(); sl@0: test.Printf(_L("------- End of TestNonDriveFilters Test ------------------------------\n")); sl@0: // sl@0: // 5. Add notifications for 2 file creations sl@0: // Create 2 clients sl@0: // The clients create a file each sl@0: // sl@0: PrintLine(); sl@0: __UHEAP_MARK; sl@0: r = TestTwoDoersL(); sl@0: __UHEAP_MARKEND; sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of TwoDoers Test -----------------------------------------\n")); sl@0: // sl@0: // 6. Create 2 file server sessions sl@0: // Add a notification on each session for the same specific file creation sl@0: // Create that file sl@0: // sl@0: PrintLine(); sl@0: __UHEAP_MARK; sl@0: r = TestTwoWatchersL(); sl@0: __UHEAP_MARKEND; sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of TwoWatchers Test --------------------------------------\n")); sl@0: // sl@0: // 7. Create 2 file server sessions and 2 clients sl@0: // Add a notification on each session for different file creations sl@0: // Clients create a file each sl@0: // sl@0: PrintLine(); sl@0: __UHEAP_MARK; sl@0: r = TestTwoWatchersTwoDoersL(); sl@0: __UHEAP_MARKEND; sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of TwoWatchersTwoDoers Test ------------------------------\n")); sl@0: // sl@0: // 8. Add notification for a specific file creation sl@0: // Cancel the notification request sl@0: // Create that file sl@0: // sl@0: PrintLine(); sl@0: __UHEAP_MARK; sl@0: r = TestCancelNotificationL(); sl@0: __UHEAP_MARKEND; sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of CancelNotification Test -------------------------------\n")); sl@0: // sl@0: // 9. Create 2 file server sessions sl@0: // Add a notification on each session for the same specific file creation sl@0: // Delete the first notification sl@0: // Create that file sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("TestClientRemoval")); sl@0: __UHEAP_MARK; sl@0: r = TestClientRemovalL(); sl@0: __UHEAP_MARKEND; sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of TestClientRemoval Test --------------------------------\n")); sl@0: // sl@0: // 10. Create a CFsNotify object sl@0: // Close the session before closing the subsession sl@0: // Add notification and request notifications sl@0: // sl@0: PrintLine(); sl@0: __UHEAP_MARK; sl@0: // Close session after creating the object sl@0: TestSessionClose(1); sl@0: __UHEAP_MARKEND; sl@0: __UHEAP_MARK; sl@0: // Close session after adding the notification sl@0: TestSessionClose(2); sl@0: __UHEAP_MARKEND; sl@0: test.Printf(_L("------- End of TestSessionClose Test ---------------------------------\n")); sl@0: sl@0: sl@0: //========================================================================================= sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2444 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc File/Directory Create and Replace – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: //! sl@0: //! TFsNotificationType ECreate sl@0: //========================================================================================= sl@0: // sl@0: // RFile::Create sl@0: // 1. Add notification for a specific file creation sl@0: // Create that file sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("EFileCreate Tests")); sl@0: _LIT(KFilename3,"file.create"); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename3,5,5,t_notification::EFileCreate,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of EFileCreate Tests -------------------------------------\n")); sl@0: // sl@0: // RFs::MkDir sl@0: // 2. Add notification for a specific directory creation sl@0: // Create that directory sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("EFsMkDir Test")); sl@0: _LIT(KDirName1,"dirCreate\\"); sl@0: r = TestMultipleNotificationsL(KDirName1,_L(""),1,1,t_notification::EFsMkDir,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of EFsMkDir Test -----------------------------------------\n")); sl@0: // sl@0: // RFile::Replace sl@0: // 3. Add notification for a specific file creation sl@0: // Replace that file sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("EFileReplace Test")); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename3,1,1,t_notification::EFileReplace,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of EFileReplace Test -------------------------------------\n")); sl@0: // sl@0: // 4. Add notification for a specific file creation sl@0: // Remove that notification sl@0: // Create that file sl@0: // sl@0: PrintLine(); sl@0: __UHEAP_MARK; sl@0: r = TestAddRemoveNotificationL(); sl@0: __UHEAP_MARKEND; sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of Add and Remove Notification Test ----------------------\n")); sl@0: // sl@0: // Wildcard Create Tests sl@0: // 5. Add notification for file creation using wildcard name sl@0: // Add notification for file/directory wildcard including subdirectories sl@0: // Create number of files and directories that match each notification sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("Wildcard Create Tests")); sl@0: // sl@0: // Wildcard Name sl@0: _LIT(KWildcardName1,"*"); sl@0: r = TestMultipleNotificationsL(_L(""),KWildcardName1,1,1,t_notification::EFileCreate,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: r = TestMultipleNotificationsL(KWildcardName1,KWildcardName1,1,1,t_notification::EFileCreate_subs,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: r = TestMultipleNotificationsL(KWildcardName1,KWildcardName1,1,1,t_notification::EFileCreate_subs_nowatch,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)ETrue,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // Wildcard including Subdirectories sl@0: _LIT(KWildcardName2,"*\\"); sl@0: r = TestMultipleNotificationsL(KWildcardName2,KWildcardName1,1,1,t_notification::EFileCreate,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)ETrue,__LINE__); sl@0: test(r==KErrNone); sl@0: r = TestMultipleNotificationsL(KWildcardName2,KWildcardName1,1,1,t_notification::EFileCreate_subs_nowatch,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: _LIT(KDirName2,"SubDir\\"); sl@0: _LIT(KWildcardName3,"?"); sl@0: r = TestMultipleNotificationsL(KDirName2,KWildcardName3,1,1,t_notification::EFileCreate_subs_nowatch,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // Wildcard Type sl@0: _LIT(KWildcardName4,"*.*"); sl@0: r = TestMultipleNotificationsL(_L(""),KWildcardName4,1,1,t_notification::EFileCreate_txt_nowatch,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: r = TestMultipleNotificationsL(_L(""),KWildcardName4,1,1,t_notification::EFileCreate_subs_nowatch,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)ETrue,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // 6. Add notification for file creation for a specific type sl@0: // Create file with that type sl@0: // Create file with different type sl@0: // sl@0: _LIT(KWildcardName5,"*.txt"); sl@0: r = TestMultipleNotificationsL(_L(""),KWildcardName5,1,1,t_notification::EFileCreate_txt,TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of Wildcard Create Tests ---------------------------------\n")); sl@0: sl@0: sl@0: //============================================================================= sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2445 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc File Attribute Change – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: // sl@0: // TFsNotificationType EAttribute sl@0: //============================================================================= sl@0: // sl@0: // RFile::SetAtt, RFile::Set and RFs::SetEntry sl@0: // 1. Add notification for a specific file attribute change sl@0: // Change the attribute for that file sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("Attribute Tests")); sl@0: _LIT(KFilename4,"file.setatts"); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename4,1,1,t_notification::EFileSetAtt,TFsNotification::EAttribute,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename4,1,1,t_notification::EFileSet,TFsNotification::EAttribute,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename4,1,1,t_notification::EFsSetEntry,TFsNotification::EAttribute,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // Wildcard Attribute Test including subdirectories sl@0: // 2. Add notification for file attribute change using wildcard name sl@0: // Create number of files that match the notification sl@0: // Change attributes of some files sl@0: // sl@0: r = TestMultipleNotificationsL(KWildcardName2,_L("*"),3,3,t_notification::EFileSetAtt_subs,TFsNotification::EAttribute,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of Attribute Tests ---------------------------------------\n")); sl@0: sl@0: sl@0: //============================================================================= sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2446 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc File/Directory Rename – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: // sl@0: // TFsNotificationType ERename sl@0: //============================================================================= sl@0: // sl@0: // RFs::Replace, RFs::Rename and RFile::Rename sl@0: // 1. Add notification for a specific file rename change sl@0: // Rename that file sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("Rename Tests")); sl@0: _LIT(KFilename5,"file.rename"); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename5,1,1,t_notification::EFsReplace,TFsNotification::ERename,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename5,1,1,t_notification::EFsRename,TFsNotification::ERename,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename5,1,1,t_notification::EFileRename,TFsNotification::ERename,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // 2. Add notification for a specific directory rename sl@0: // Rename that directory sl@0: // sl@0: _LIT(KDirName3,"dirRename\\"); sl@0: r = TestMultipleNotificationsL(KDirName3,_L(""),1,1,t_notification::EFsRename_dir,TFsNotification::ERename,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // 3. Add notification for file rename using wildcard name sl@0: // Create file that match the notification sl@0: // Repeatedly rename the file sl@0: // sl@0: r = TestMultipleNotificationsL(_L(""),KWildcardName1,3,3,t_notification::EFileRename_wild,TFsNotification::ERename,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of Rename Tests ------------------------------------------\n")); sl@0: sl@0: sl@0: //============================================================================= sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2447 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc File/Directory Delete – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: // sl@0: // TFsNotificationType EDelete sl@0: //============================================================================= sl@0: // sl@0: // RFs::Delete sl@0: // 1. Add notification for a specific file delete sl@0: // Delete that file sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("EFsDelete Test")); sl@0: _LIT(KFilename6,"file.delete"); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename6,1,1,t_notification::EFsDelete,TFsNotification::EDelete,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // RFs::RmDir sl@0: // 2. Add notification for a specific directory delete sl@0: // Delete that directory sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("EFsRmDir Tests")); sl@0: _LIT(KDirName4,"dirRemove\\"); sl@0: r = TestMultipleNotificationsL(KDirName4,_L(""),1,1,t_notification::EFsRmDir,TFsNotification::EDelete,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // This test should not receive any notifications because a non-empty directory cannot be removed sl@0: // 3. Add notification for specific directory delete sl@0: // Create files inside that directory sl@0: // Delete the directory sl@0: // sl@0: _LIT(KDirName5,"dirRmNonEmp\\"); sl@0: r = TestMultipleNotificationsL(KDirName5,_L(""),1,1,t_notification::EFsRmDir_nonEmpty,TFsNotification::EDelete,KMinNotificationBufferSize,(TBool)ETrue,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // Wildcard Name ("*") sl@0: // 4. Add notification for directory delete using wildcard name sl@0: // Create directory that match the notification sl@0: // Delete that directory sl@0: // sl@0: r = TestMultipleNotificationsL(KWildcardName1,_L(""),1,1,t_notification::EFsRmDir_wild,TFsNotification::EDelete,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // Wildcard Type ("*.txt") sl@0: // Creates files with different types and should only receive notifications from "*.txt" file deletions sl@0: // 5. Add notification for file deletes using wildcard type sl@0: // Create number of files that match the notification sl@0: // Delete those files sl@0: // sl@0: r = TestMultipleNotificationsL(_L(""),KWildcardName4,3,3,t_notification::EFsDelete,TFsNotification::EDelete,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of Delete Tests ------------------------------------------\n")); sl@0: sl@0: sl@0: //====================================================================== sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2448 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc File Change – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: // sl@0: // TFsNotificationType EFileChange sl@0: //====================================================================== sl@0: // sl@0: // File Write sl@0: // If caching is enabled, notifications are received only when the file cache is flushed sl@0: // We flush everytime we do a write to ensure the tests work regardless of cache sl@0: // sl@0: // 1. Add notification for a specific file change sl@0: // Create the file sl@0: // Write to that file sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("EFileWrite Tests")); sl@0: _LIT(KFilename7,"file.write"); sl@0: __UHEAP_MARK; sl@0: r = TestMultipleNotificationsL(_L(""),KFilename7,7,7,t_notification::EFileWrite,TFsNotification::EFileChange,3*KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: __UHEAP_MARKEND; sl@0: test(r==KErrNone); sl@0: // sl@0: // 2. Add notification for a specific file change sl@0: // Write to the specified file a number of times without changing its size sl@0: // sl@0: // Four letters are written to a file, then the first letter in the file is replaced aIterations times sl@0: // aMaxNotifications = 1 + aIterations sl@0: // sl@0: r = TestMultipleNotificationsL(_L(""),KFilename7,3,4,t_notification::EFileWrite_samesize,TFsNotification::EFileChange,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of EFileWrite Tests --------------------------------------\n")); sl@0: // sl@0: // 3. Add notification for a specific file change sl@0: // Write to that file asynchronously sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("EFileWrite_async Tests")); sl@0: _LIT(KFilename8,"async.write"); sl@0: __UHEAP_MARK; sl@0: r = TestMultipleNotificationsL(_L(""),KFilename8,4,4,t_notification::EFileWrite_async,TFsNotification::EFileChange,2*KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: __UHEAP_MARKEND; sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of EFileWrite_async Tests --------------------------------\n")); sl@0: // sl@0: // File Set Size sl@0: // 4. Add notification for a specific file change sl@0: // Both increase and decrease the file sizes a number of times sl@0: // sl@0: // The file size is increased aIterations times, and decreased (aIterations - 1) times sl@0: // aMaxNotifications = 2*aIterations - 1 sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("EFileSetSize Tests")); sl@0: _LIT(KFilename9,"file.setsize"); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename9,5,9,t_notification::EFileSetSize,TFsNotification::EFileChange,3*KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of EFileSetSize Tests ------------------------------------\n")); sl@0: sl@0: sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("CFileMan Tests")); sl@0: _LIT(KFilenameCFMan,"cf1le.man"); sl@0: TUint notificationTypes = (TUint)TFsNotification::ECreate|TFsNotification::EFileChange|TFsNotification::EAttribute|TFsNotification::EDelete|TFsNotification::ERename; sl@0: r = TestMultipleNotificationsL(_L(""),KFilenameCFMan,1,5,t_notification::ECFileManMove,notificationTypes,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of CFileMan Tests -------------------------------------\n")); sl@0: sl@0: sl@0: //======================================================================================== sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2449 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc File System Mounted/Dismounted, Media Card Removal/Insertion, sl@0: // RawDisk Write – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: // sl@0: // TFsNotificationType EMediaChange sl@0: //======================================================================================== sl@0: // sl@0: // RFs::DismountFileSystem sl@0: // 1. Add notification for media change sl@0: // Dismount the file system sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("Mount Tests")); sl@0: TFullName filesystemName; sl@0: r = TheFs.FileSystemName(filesystemName,globalDriveNum); sl@0: test(r==KErrNone); sl@0: r = TestMultipleNotificationsL(filesystemName,1,1,t_notification::EDismount,TFsNotification::EMediaChange,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // RFs::MountFileSystem sl@0: // 2. Add notification for media change sl@0: // Mount the file system sl@0: // sl@0: r = TestMultipleNotificationsL(filesystemName,1,1,t_notification::EMount,TFsNotification::EMediaChange,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // Repeatedly mount and dismount the file system sl@0: // 3. Add notification for media change sl@0: // Repeatedly dismount and mount the file system sl@0: // sl@0: // The file system is dismounted and mounted aIterations times sl@0: // aMaxNotifications = 2*aIterations sl@0: // sl@0: r = TestMultipleNotificationsL(filesystemName,5,10,t_notification::EMountDismount,TFsNotification::EMediaChange,3*KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // RFs::MountFileSystemAndScan sl@0: // 4. Add notification for media change sl@0: // Mount and scan the file system sl@0: // sl@0: // The file system is dismounted and mounted aIterations times sl@0: // aMaxNotifications = 2*aIterations sl@0: // sl@0: //#ifndef __WINS__ sl@0: // r = TestMultipleNotificationsL(filesystemName,1,2,t_notification::EMountScan,TFsNotification::EMediaChange,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: // test(r==KErrNone); sl@0: //#endif sl@0: test.Printf(_L("------- End of Mount Tests -------------------------------------------\n")); sl@0: TDriveInfo drvInfo; sl@0: TInt driveNum; sl@0: TheFs.CharToDrive(gDriveToTest,driveNum); sl@0: r = TheFs.Drive(drvInfo,driveNum); sl@0: test (r == KErrNone); sl@0: TPtrC driveDes((TText*)&gDriveToTest,1); sl@0: // sl@0: // Manual Tests - Will only run on removable drives sl@0: // sl@0: /* if(drvInfo.iDriveAtt & KDriveAttRemovable) sl@0: { sl@0: // sl@0: // 5. Add notification for media change sl@0: // Remove media card manually sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("Media Card Removal/Insertion Tests")); sl@0: r = TestMultipleNotificationsL(driveDes,1,1,t_notification::EMediaCardRemoval,TFsNotification::EMediaChange,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // 6. Add notification for media change sl@0: // Insert media card manually sl@0: // sl@0: r = TestMultipleNotificationsL(driveDes,1,1,t_notification::EMediaCardInsertion,TFsNotification::EMediaChange,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of Media Card Removal/Insertion Tests --------------------\n")); sl@0: // sl@0: // We should receive an EMediaChange notification even though we did not register for it sl@0: // 7. Do not add notification for media change sl@0: // Remove and insert media card manually sl@0: // sl@0: PrintLine(); sl@0: TestMediaCardNotificationWhenNotRegisteredForIt(); sl@0: test.Printf(_L("------- End of TestMediaCardNotificationWhenNotRegisteredForIt -------\n")); sl@0: } sl@0: */ // sl@0: // RRawDisk::Write sl@0: // 8. Add notification for media change sl@0: // Write directly to the media sl@0: // sl@0: #ifdef __WINS__ sl@0: if(gDriveToTest-(TChar)'A' != 2) sl@0: #endif sl@0: { sl@0: PrintLine(); sl@0: test.Next(_L("RRawDisk::Write Tests")); sl@0: r = TestMultipleNotificationsL(driveDes,1,1,t_notification::ERawDiskWrite,TFsNotification::EMediaChange,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of RRawDisk::Write Test ------------------------------ \n")); sl@0: } sl@0: sl@0: sl@0: //=============================================================================== sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2450 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc Drive Name Modification – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: // sl@0: // TFsNotificationType EDriveName sl@0: //=============================================================================== sl@0: // sl@0: // RFs::SetDriveName sl@0: // The drive name is renamed 2*aIterations times sl@0: // aMaxNotifications = 2*aIterations sl@0: // sl@0: // 1. Add notification for a specific drive name change sl@0: // Change the drive name sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("DriveName Test")); sl@0: r = TestMultipleNotificationsL(driveDes,1,2,t_notification::ESetDriveName,TFsNotification::EDriveName,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // 2. Add notification for a specific drive name change sl@0: // Repeatedly rename the drive sl@0: // sl@0: r = TestMultipleNotificationsL(driveDes,3,6,t_notification::ESetDriveName,TFsNotification::EDriveName,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of DriveName Test ----------------------------------------\n")); sl@0: sl@0: sl@0: //================================================================================ sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2451 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc Volume Name Modification – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: // sl@0: // TFsNotificationType EVolumeName sl@0: //================================================================================ sl@0: // sl@0: // RFs::SetVolumeLabel - Does not run on WINS sl@0: // The volume name is renamed 2*aIterations times sl@0: // aMaxNotifications = 2*aIterations sl@0: // sl@0: #ifndef __WINS__ sl@0: PrintLine(); sl@0: test.Next(_L("VolumeName Test")); sl@0: // sl@0: // 1. Add notification for a specific volume name change sl@0: // Change the volume name sl@0: // sl@0: r = TestMultipleNotificationsL(driveDes,1,2,t_notification::ESetVolumeLabel,TFsNotification::EVolumeName,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // 2. Add notification for a specific volume name change sl@0: // Repeatedly rename the volume sl@0: // sl@0: r = TestMultipleNotificationsL(driveDes,3,6,t_notification::ESetVolumeLabel,TFsNotification::EVolumeName,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of VolumeName Test ---------------------------------------\n")); sl@0: #endif sl@0: sl@0: sl@0: //============================================================================= sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2452 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc All Operations Filter – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: // sl@0: // TFsNotificationType EAllOps sl@0: //============================================================================= sl@0: PrintLine(); sl@0: test.Next(_L("AllOps Tests")); sl@0: // sl@0: // 1. Add notification for all operations sl@0: // Create a file sl@0: // Delete the file sl@0: // sl@0: // EAllOps1: A file is created and deleted aIterations times sl@0: // aMaxNotification = 2*aIterations sl@0: // sl@0: _LIT(KFilename10,"file.allops"); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename10,4,8,t_notification::EAllOps1,(TUint)TFsNotification::EAllOps,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // 2. Add notification for all operations sl@0: // Create a file sl@0: // Write to the file sl@0: // Delete the file sl@0: // sl@0: // EAllOps2: A file is created, written to aIterations times and then deleted sl@0: // aMaxNotification = 2 + aIterations (See File Write Tests) sl@0: // sl@0: r = TestMultipleNotificationsL(_L(""),KFilename10,4,6,t_notification::EAllOps2,(TUint)TFsNotification::EAllOps,2*KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // 3. Add notification for all operations sl@0: // Create a file sl@0: // Change the file size sl@0: // Delete the file sl@0: // sl@0: // EAllOps3: A file is created, its size is increased size aIterations times, decreased (aIterations - 1) times sl@0: // and then deleted sl@0: // aMaxNotifications = 1 + 2*aIterations sl@0: // sl@0: r = TestMultipleNotificationsL(_L(""),KFilename10,4,9,t_notification::EAllOps3,(TUint)TFsNotification::EAllOps,KMinNotificationBufferSize*2,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // 4. Add notification for all operations sl@0: // Create a file sl@0: // Change the file attribute sl@0: // Delete the file sl@0: // sl@0: // EAllOps4: A file is created, its attribute is changed and the file is deleted sl@0: // aMaxNotification = 3 sl@0: // sl@0: r = TestMultipleNotificationsL(_L(""),KFilename10,1,3,t_notification::EAllOps4,(TUint)TFsNotification::EAllOps,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // 5. Add notification for all operations sl@0: // Create a file sl@0: // Rename the file sl@0: // sl@0: // EAllOps5: A file is created and renamed sl@0: // aMaxNotification = 2 sl@0: // sl@0: r = TestMultipleNotificationsL(_L(""),KFilename10,1,2,t_notification::EAllOps5,(TUint)TFsNotification::EAllOps,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // 6. Add notification for all operations sl@0: // Change drive name sl@0: // Change volume name sl@0: // sl@0: // SetVolumeLabel does not run on WINS sl@0: // EAllOps6: The drive and volume names are changed sl@0: // aMaxNotification = 2 sl@0: // sl@0: #ifndef __WINS__ sl@0: r = TestMultipleNotificationsL(driveDes,1,2,t_notification::EAllOps6,(TUint)TFsNotification::EAllOps,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: #endif sl@0: test.Printf(_L("------- End of AllOps Tests ------------------------------------------\n")); sl@0: sl@0: sl@0: //============================================================================= sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2453 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc Multiple Filters – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: //============================================================================= sl@0: PrintLine(); sl@0: test.Next(_L("Multiple-Filter Tests")); sl@0: // sl@0: // TFsNotification::ECreate | TFsNotification::EDelete sl@0: // 1. Add notification for create and delete for a specific file sl@0: // Create that file sl@0: // Delete the file sl@0: // sl@0: // A file is created and deleted aIterations times sl@0: // aMaxNotification = 2*aIterations sl@0: // sl@0: _LIT(KFilename11,"file.mulfil"); sl@0: r = TestMultipleNotificationsL(_L(""),KFilename11,3,6,t_notification::EAllOps1,TFsNotification::ECreate | TFsNotification::EDelete,2*KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // TFsNotification::EDelete | TFsNotification::ECreate | TFsNotification::EFileChange sl@0: // 2. Add notification for create, file change and delete for a specific file sl@0: // Create a file sl@0: // Change the file size sl@0: // Delete the file sl@0: // sl@0: // A file is created, its size is increased size aIterations times, decreased (aIterations - 1) times sl@0: // and then deleted sl@0: // aMaxNotifications = 1 + 2*aIterations sl@0: // sl@0: r = TestMultipleNotificationsL(_L(""),KFilename11,4,9,t_notification::EAllOps3,TFsNotification::EDelete | TFsNotification::ECreate | TFsNotification::EFileChange,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // TFsNotification::EAttribute | TFsNotification::EDelete | TFsNotification::ECreate sl@0: // 3. Add notification for create, attribute change and delete for a specific file sl@0: // Create a file sl@0: // Change the file attribute sl@0: // Delete the file sl@0: // sl@0: // A file is created, its attribute is changed and the file is deleted sl@0: // aMaxNotification = 3 sl@0: // sl@0: r = TestMultipleNotificationsL(_L(""),KFilename11,1,3,t_notification::EAllOps4,TFsNotification::EAttribute | TFsNotification::EDelete | TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // TFsNotification::ERename | TFsNotification::ECreate sl@0: // 4. Add notification for create and rename for a specific file sl@0: // Create a file sl@0: // Rename the file sl@0: // sl@0: // A file is created and renamed sl@0: // aMaxNotification = 2 sl@0: // sl@0: r = TestMultipleNotificationsL(_L(""),KFilename11,1,2,t_notification::EAllOps5,TFsNotification::ERename | TFsNotification::ECreate,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: // sl@0: // TFsNotification::EVolumeName | TFsNotification::EDriveName sl@0: // 5. Add notification for drive and volume name change for a specific drive sl@0: // Change drive name sl@0: // Change volume name sl@0: // sl@0: // SetVolumeLabel does not run on WINS sl@0: // The drive and volume names are changed sl@0: // aMaxNotification = 2 sl@0: // sl@0: #ifndef __WINS__ sl@0: r = TestMultipleNotificationsL(driveDes,1,2,t_notification::EAllOps6,TFsNotification::EVolumeName | TFsNotification::EDriveName,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: #endif sl@0: test.Printf(_L("------- End of Multiple-Filter Tests ---------------------------------\n")); sl@0: sl@0: sl@0: //============================================================================== sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2454 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc Overflow Notification – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: //============================================================================== sl@0: // sl@0: // 1. Add notification with a small buffer size, for a specific file change sl@0: // Change the file size once sl@0: // 2. Make continuous file size changes to the file sl@0: // 3. When overflow notification occurs, delete the notification sl@0: // sl@0: PrintLine(); sl@0: r = TestOverflowL(); sl@0: test(r==KErrNone); sl@0: sl@0: //For DEF140387 sl@0: PrintLine(); sl@0: r= TestPostOverflowNotifications(); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of Overflow Test -----------------------------------------\n")); sl@0: sl@0: sl@0: //============================================================================ sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2455 sl@0: //! @SYMTestType CIT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc API Negative Testing – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: //============================================================================ sl@0: // 1. sl@0: // a-CFsNotify class creation with zero buffer size sl@0: // sl@0: // 2. sl@0: // b-CFsNotify class creation with negative buffer size sl@0: // c-CFsNotify class creation with buffer size that is too large sl@0: // sl@0: // 3. sl@0: // d-Call AddNotification with aNotiififcationType zero sl@0: // e-Call AddNotification with aNotiififcationType invalid sl@0: // f-Call AddNotification with many different invalid paths sl@0: // sl@0: // 4. sl@0: // g-Call RequestNotifications with status that is already in use sl@0: // h-Call CancelNotifications with wrong status sl@0: // sl@0: PrintLine(); sl@0: __UHEAP_MARK; sl@0: NegativeTests(); sl@0: __UHEAP_MARKEND; sl@0: // sl@0: // 5. sl@0: // i-Negative testing for directory without * sl@0: // sl@0: test.Printf(_L("NegativeTests() I\n")); sl@0: NegativeTestDirStar(); sl@0: test.Printf(_L("------- End of Negative Tests ----------------------------------------\n")); sl@0: sl@0: sl@0: //============================================================================= sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2461 sl@0: //! @SYMTestType CIT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc Plugin Tests sl@0: //! @SYMTestStatus sl@0: //============================================================================= sl@0: PrintLine(); sl@0: r = TestNotificationsWithFServPlugins(); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of Plugin Tests ------------------------------------------\n")); sl@0: sl@0: sl@0: //====================================================================== sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2459 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc Drive Formatting – Single File Server Session sl@0: //! @SYMTestStatus Implemented sl@0: // sl@0: // TFsNotificationType EMediaChange sl@0: //====================================================================== sl@0: // sl@0: // RFormat sl@0: // We do these last so that we can be sure to have deleted anything we've inadvertently not deleted sl@0: // sl@0: // 1. Add notification for media change of a specific drive sl@0: // Format the drive sl@0: // sl@0: #ifdef __WINS__ sl@0: if(gDriveToTest-(TChar)'A' != 2) sl@0: #endif sl@0: { sl@0: PrintLine(); sl@0: test.Next(_L("Format Tests")); sl@0: r = TestMultipleNotificationsL(driveDes,1,1,t_notification::EFormat,TFsNotification::EMediaChange,KMinNotificationBufferSize,(TBool)EFalse,__LINE__); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("------- End of Format Tests ------------------------------------------\n")); sl@0: } sl@0: sl@0: sl@0: //====================================================================== sl@0: //! @SYMTestCaseID PBASE-T_NOTIFY-2460 sl@0: //! @SYMTestType UT sl@0: //! @SYMREQ PREQ1847 sl@0: //! @SYMTestCaseDesc Notifications for Data Caged Areas sl@0: //! @SYMTestStatus Implemented sl@0: //====================================================================== sl@0: // sl@0: // Create a private folder for a specified uid sl@0: // Add notification filter using the following processes: sl@0: // 1. A process with no capability sl@0: // 2. A process with all capabilities sl@0: // 3. A process with the specified uid sl@0: // sl@0: PrintLine(); sl@0: test.Next(_L("Test T_NOTIFIER_NOCAPS.EXE")); sl@0: r = TestProcessCapabilities(_L("T_NOTIFIER_NOCAPS.EXE")); sl@0: test(r == KErrPermissionDenied); //Failure on emulator -> Did you forget to do a wintest? sl@0: sl@0: test.Next(_L("Test T_NOTIFIER_ALLFILES.EXE")); sl@0: r = TestProcessCapabilities(_L("T_NOTIFIER_ALLFILES.EXE")); sl@0: test(r == KErrNone); sl@0: sl@0: test.Next(_L("Test T_NOTIFIER_BELONGS.EXE")); sl@0: r = TestProcessCapabilities(_L("T_NOTIFIER_BELONGS.EXE")); sl@0: test(r == KErrNone); sl@0: test.Printf(_L("------- End of Data-Caging Tests -------------------------------------\n")); sl@0: sl@0: sl@0: test.End(); sl@0: test.Close(); sl@0: delete cleanup; sl@0: } //End of CallTestsL sl@0: