sl@0: // Copyright (c) 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\bench\t_notify_perf_util.cpp sl@0: // sl@0: // sl@0: sl@0: #include "t_notify_perf.h" sl@0: #include "t_server.h" sl@0: sl@0: void DoKillThreadsL() sl@0: { sl@0: TInt count = 0; sl@0: while (count < gNotiThreads.Count()) sl@0: { sl@0: gNotiThreads[count].Kill(KErrGeneral); sl@0: count++; sl@0: } sl@0: gFileThread.Kill(KErrGeneral); sl@0: } sl@0: sl@0: // Safe way of checking in sub threads, it leaves when check fails, Main thread will catch the error and exit. sl@0: // if use test() directly in sub-threads, the threads may hang if check fails sl@0: void SafeTestL(TBool aResult, TInt aId, TInt aLine, TText* aFile) sl@0: { sl@0: if (!aResult) sl@0: { sl@0: if (aId >= 0) sl@0: { sl@0: RDebug::Print(_L("NotificationThread%02d: Failed check in %s at line %d"), aId, aFile, aLine); sl@0: } sl@0: else if (aId == KNoThreadId) sl@0: { sl@0: RDebug::Print(_L("Failed check in %s at line %d"), aFile, aLine); sl@0: } sl@0: CTestExecutor::KillAllTestThreads(); sl@0: } sl@0: } sl@0: sl@0: void SafeTestL(TInt aResult, TInt aExpected, TInt aId, TInt aLine, TText* aFile) sl@0: { sl@0: if (aResult != aExpected) sl@0: { sl@0: if (aId >= 0) sl@0: { sl@0: RDebug::Print(_L("NotificationThread%02d: Failed check in %s at line %d, expected %d, got %d"), aId, aFile, aLine, aExpected, aResult); sl@0: } sl@0: else if (aId == KNoThreadId) sl@0: { sl@0: RDebug::Print(_L("Failed check in %s at line %d, expected %d, got %d"), aFile, aLine, aExpected, aResult); sl@0: } sl@0: CTestExecutor::KillAllTestThreads(); sl@0: } sl@0: } sl@0: sl@0: void SetTestPaths() sl@0: { sl@0: gTestPath.FillZ(); sl@0: gLogFilePath.FillZ(); sl@0: sl@0: gTestPath.Append(gDriveToTest); sl@0: gTestPath.Append(_L(":\\F32-TST\\T_Notify_Perf\\")); sl@0: sl@0: #ifndef __WINSCW__ sl@0: gLogFilePath.Append(gDriveToTest); sl@0: #else sl@0: gLogFilePath.Append((TChar)'C'); //If emulator lets stick it on C: (\epoc32\wisncw\c\) sl@0: #endif sl@0: if (gPerfMeasure) sl@0: gLogFilePath.Append(_L(":\\F32-TST\\NPTestLog\\")); sl@0: else sl@0: gLogFilePath.Append(_L(":\\F32-TST\\Temp\\")); sl@0: } sl@0: sl@0: // Mapping from file operations to notification types sl@0: TUint OpNotifyMapping(TUint16& aOption, TInt aOperation) sl@0: { sl@0: if (aOption & EEnhanced) sl@0: { sl@0: switch(aOperation) sl@0: { sl@0: case EOpCreate: sl@0: case EOpCreateDir: sl@0: return TFsNotification::ECreate; sl@0: case EOpReplace: sl@0: case EOpRename: sl@0: case EOpRenameDir: sl@0: return TFsNotification::ERename; sl@0: case EOpChgAttr: sl@0: return TFsNotification::EAttribute; sl@0: case EOpWrite: sl@0: case EOpResize: sl@0: case EOpManyChanges: sl@0: case EOpManyFiles: sl@0: return TFsNotification::EFileChange; sl@0: case EOpDelete: sl@0: case EOpDeleteDir: sl@0: return TFsNotification::EDelete; sl@0: case EOpMixed: sl@0: return (TUint) (TFsNotification::EAllOps & (~TFsNotification::EOverflow)); sl@0: default: sl@0: return (TUint) TFsNotification::EAllOps; sl@0: } sl@0: } sl@0: else if (aOption & EOriginal) sl@0: { sl@0: switch(aOperation) sl@0: { sl@0: case EOpCreate: sl@0: case EOpReplace: sl@0: case EOpRename: sl@0: return ENotifyFile; sl@0: case EOpChgAttr: sl@0: case EOpResize: sl@0: return ENotifyAttributes; sl@0: case EOpWrite: sl@0: case EOpManyChanges: sl@0: case EOpManyFiles: sl@0: return ENotifyWrite; sl@0: case EOpDelete: sl@0: return ENotifyEntry; sl@0: case EOpCreateDir: sl@0: case EOpRenameDir: sl@0: case EOpDeleteDir: sl@0: return ENotifyDir; sl@0: case EOpMixed: sl@0: default: sl@0: return ENotifyAll; sl@0: } sl@0: } sl@0: else if (aOption & EPlugin) sl@0: { sl@0: switch(aOperation) sl@0: { sl@0: case EOpCreate: sl@0: return EMdsFileCreated; sl@0: case EOpReplace: sl@0: return EMdsFileReplaced; sl@0: case EOpRename: sl@0: return EMdsFileRenamed; sl@0: case EOpDelete: sl@0: return EMdsFileDeleted; sl@0: case EOpRenameDir: sl@0: return EMdsDirRenamed; sl@0: default: sl@0: // All other operations are not testable sl@0: return EMdsFileUnknown; sl@0: } sl@0: } sl@0: return 0; sl@0: } sl@0: sl@0: // generate file names for testing sl@0: void FileNameGen(TFileName& aName, TInt aNum, TBool aIsFile = ETrue) sl@0: { sl@0: aName.FillZ(); sl@0: aName.Copy(gTestPath); sl@0: if (aIsFile) sl@0: aName.AppendFormat(_L("%04d.tst"), aNum); sl@0: else sl@0: aName.AppendFormat(_L("DIR%04d\\"), aNum); sl@0: } sl@0: sl@0: void ClearTestPathL() sl@0: { sl@0: RDebug::Print(_L("Clearing test path...")); sl@0: RFs fs; sl@0: User::LeaveIfError(fs.Connect()); sl@0: CFileMan* fm = CFileMan::NewL(fs); sl@0: TInt r = fm->RmDir(gTestPath); sl@0: test(r==KErrNone || r==KErrPathNotFound || r==KErrNotFound); sl@0: r = fs.MkDirAll(gTestPath); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: sl@0: delete fm; sl@0: fs.Close(); sl@0: } sl@0: sl@0: void DeleteLogFilesL() sl@0: { sl@0: RDebug::Print(_L("Clearing test logs if exist...")); sl@0: RFs fs; sl@0: User::LeaveIfError(fs.Connect()); sl@0: CFileMan* fm = CFileMan::NewL(fs); sl@0: sl@0: TFileName logFiles; sl@0: logFiles.Copy(gLogFilePath); sl@0: logFiles.Append('*'); sl@0: logFiles.Append(gLogPostFix); sl@0: sl@0: TInt r = fm->Delete(logFiles); sl@0: test(r==KErrNone || r==KErrPathNotFound || r==KErrNotFound); sl@0: if (r != KErrNone) sl@0: { sl@0: r = fs.MkDirAll(gLogFilePath); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: } sl@0: sl@0: delete fm; sl@0: fs.Close(); sl@0: } sl@0: sl@0: // Copy log files from test drive to MMC sl@0: void CopyLogFilesL() sl@0: { sl@0: RFs fs; sl@0: User::LeaveIfError(fs.Connect()); sl@0: CFileMan* fm = CFileMan::NewL(fs); sl@0: sl@0: TFileName path; sl@0: path.Append(_L("D:\\NPTLogs\\")); sl@0: TInt r = fs.MkDirAll(path); sl@0: test(r == KErrNone || r == KErrAlreadyExists); sl@0: fm->Copy(gLogFilePath, path); sl@0: sl@0: delete fm; sl@0: fs.Close(); sl@0: } sl@0: sl@0: // compare the name of two entries sl@0: TBool CompareEntryName(const TEntry& aEntry1, const TEntry& aEntry2) sl@0: { sl@0: return (aEntry1.iName.Compare(aEntry2.iName) == 0); sl@0: } sl@0: sl@0: // start file operations sl@0: void DoFileOperationL(TThreadParam* aParam) sl@0: { sl@0: CFileOperator fileOperator(aParam->iSetting, *(aParam->iLoggerArray), aParam->iSmphFT, aParam->iSmphNT); sl@0: fileOperator.DoChangesL(); sl@0: } sl@0: sl@0: // start monitoring notification sl@0: void DoNotificationOperationL(TThreadParam* aParam) sl@0: { sl@0: CActiveScheduler* sch = new(ELeave) CActiveScheduler(); sl@0: CleanupStack::PushL(sch); sl@0: CActiveScheduler::Install(sch); sl@0: sl@0: CNotifyOperator notifyOperator(aParam->iSetting, aParam->iSmphFT, aParam->iSmphNT, aParam->iLogger); sl@0: aParam->iSmphFT->Signal(); sl@0: notifyOperator.StartOperationL(); sl@0: sl@0: CleanupStack::PopAndDestroy(); sl@0: } sl@0: sl@0: // entry function of file operaton thread sl@0: TInt FileOperationThread(TAny* aParam) sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: sl@0: TRAPD(r, DoFileOperationL(static_cast(aParam))); sl@0: sl@0: delete cleanup; sl@0: sl@0: return r; sl@0: } sl@0: sl@0: // entry function of notification thread sl@0: TInt NotificationOperationThread(TAny* aParam) sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: sl@0: TRAPD(r, DoNotificationOperationL(static_cast(aParam))); sl@0: sl@0: delete cleanup; sl@0: sl@0: return r; sl@0: } sl@0: sl@0: TInt KillerThread(TAny*) sl@0: { sl@0: CTrapCleanup* cleanup; sl@0: cleanup = CTrapCleanup::New(); sl@0: sl@0: TRAPD(r, DoKillThreadsL()); sl@0: sl@0: delete cleanup; sl@0: sl@0: return r; sl@0: }