|
1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // f32test\bench\t_notify_perf.h |
|
15 // |
|
16 // |
|
17 |
|
18 #include <f32file.h> |
|
19 #include <f32file_private.h> |
|
20 #include <e32test.h> |
|
21 #include <e32svr.h> |
|
22 #include <hal.h> |
|
23 #include <e32math.h> |
|
24 #include <e32std.h> |
|
25 |
|
26 // File operation made in test path to trigger notifications |
|
27 enum TNotifyPerfTestOperations |
|
28 { |
|
29 // File Operations |
|
30 EOpEnd, // indicates that a series of operations ended |
|
31 EOpCreate, |
|
32 EOpReplace, |
|
33 EOpChgAttr, |
|
34 EOpRename, |
|
35 EOpWrite, |
|
36 EOpResize, |
|
37 EOpDelete, |
|
38 EOpManyChanges, // Large number changes to a single file |
|
39 EOpManyFiles, // Small changes to large number of files |
|
40 |
|
41 // Directory Operations |
|
42 EOpCreateDir, |
|
43 EOpRenameDir, |
|
44 EOpDeleteDir, |
|
45 |
|
46 // Mixed Operations |
|
47 EOpMixed // A series of mixed operations involving both Files and Dirs |
|
48 }; |
|
49 |
|
50 enum TTestOptions |
|
51 { |
|
52 ////////////////////////////////////////////////////// |
|
53 // Lowest 4 bit reserved for notification treads ID // |
|
54 ////////////////////////////////////////////////////// |
|
55 |
|
56 // Test with a lot of filters for enhanced notification - 1st bit |
|
57 // set - on; unset - off |
|
58 EBigFilter = 0x0010, |
|
59 |
|
60 // Whether perform full directory scan and save the file changes to a list - 2nd bit |
|
61 // set - perform; unset - not perform |
|
62 EReportChg = 0x0020, |
|
63 |
|
64 // Whether use big buffer for enhanced notification- 3rd bit |
|
65 // Set - big buffer(no overflow); unset - small(could have overflow) |
|
66 EBigBuffer = 0x0040, |
|
67 |
|
68 // For multi clients test. Enhanced Notification Only! |
|
69 // Mode 1: set a variety of different notifications, same on each clients - 4th bit |
|
70 EMultiNoti1 = 0x0080, |
|
71 |
|
72 // For multi clients test. Enhanced Notification Only! |
|
73 // Mode 2: set a variety of different notifications, in which some are different on each clients, |
|
74 // and some are same on each clients, only support upto 4 clients - 5th bit |
|
75 EMultiNoti2 = 0x0100, |
|
76 |
|
77 ENotPerfTestReserved6 = 0x0200, |
|
78 ENotPerfTestReserved7 = 0x0400, |
|
79 ENotPerfTestReserved8 = 0x0800, |
|
80 |
|
81 // Notification type - 13th - 16th bits |
|
82 ENoNotify = 0x1000, // Test without notification |
|
83 EEnhanced = 0x2000, // Using enhanced notification APIs |
|
84 EOriginal = 0x4000, // Using original notification APIs |
|
85 EPlugin = 0x8000, // Using Nokia plug-in for notification |
|
86 }; |
|
87 |
|
88 // Note for Plugin Test |
|
89 // the plugin test can only be run manually because the plugin is not available in KHS code base |
|
90 // to run the test: |
|
91 // 1. enable the MACRO above in the mmp |
|
92 // 2. get a S60 environment |
|
93 // 3. copy the MdsFileServerPlugin.ptx from the release(\Winscw or \Armv5 depend on what kind of test you want to run) |
|
94 // directory of S60 to the equivalent folder of release directory of your epoc32 |
|
95 // 4. when build a rom, include the MdsFileServerPlugin.ptx file in the rom |
|
96 // 5. then you can run |
|
97 enum TMdsFSPOperation |
|
98 { |
|
99 EMdsFSPOpEnable, |
|
100 EMdsFSPOpDisable, |
|
101 EMdsFSPOpRegisterNotification, |
|
102 EMdsFSPOpAddNotificationPath, |
|
103 EMdsFSPOpRemoveNotificationPath, |
|
104 EMdsFSPOpAddIgnorePath, |
|
105 EMdsFSPOpRemoveIgnorePath, |
|
106 EMdsFSPOpNotificationCancel, |
|
107 }; |
|
108 |
|
109 class TMdsFSPStatus |
|
110 { |
|
111 public: |
|
112 TInt iFileEventType; |
|
113 TInt iDriveNumber; |
|
114 TFileName iFileName; |
|
115 TFileName iNewFileName; |
|
116 TUid iProcessId; |
|
117 }; |
|
118 |
|
119 enum TMdsFileEventType |
|
120 { |
|
121 EMdsFileCreated, |
|
122 EMdsFileRenamed, |
|
123 EMdsFileModified, |
|
124 EMdsFileReplaced, |
|
125 EMdsFileDeleted, |
|
126 EMdsDriveFormatted, |
|
127 EMdsFileUnknown, |
|
128 EMdsDirRenamed |
|
129 }; |
|
130 |
|
131 typedef TPckgBuf<TMdsFSPStatus> TMdsFSPStatusPckg; |
|
132 |
|
133 const TInt KMdsFSPluginPosition = 0x200071CD; |
|
134 _LIT(KPluginName, "MdsFileServerPlugin"); |
|
135 |
|
136 // the list of operations to be conducted during a test case |
|
137 const TUint KDefaultOpList[] = {EOpCreate, EOpReplace, EOpChgAttr, EOpRename, EOpWrite, EOpResize, EOpDelete, EOpEnd}; |
|
138 const TUint KDefaultOpListDir[] = {EOpCreateDir, EOpRenameDir, EOpDeleteDir, EOpEnd}; |
|
139 |
|
140 const TUint KManyChangesOpList[] = {EOpManyChanges, EOpManyChanges, EOpManyChanges, EOpManyChanges, EOpManyChanges, EOpEnd}; |
|
141 const TUint KManyFilesOpList[] = {EOpManyFiles, EOpManyFiles, EOpManyFiles, EOpManyFiles, EOpManyFiles, EOpEnd}; |
|
142 const TUint KMixedOpTestList[] = {EOpMixed, EOpMixed, EOpMixed, EOpMixed, EOpMixed, EOpEnd}; |
|
143 |
|
144 const TUint16 KNotifyOptionMask = 0xF000; |
|
145 const TUint16 KNotifyTreadIdMask = 0x000F; |
|
146 |
|
147 // default time scale for timer |
|
148 const TUint KDefaultTimeScale = 1000; // 1ms |
|
149 const TInt KMaxHeapSize = 0x1000000; |
|
150 |
|
151 // used by SafeCheck |
|
152 const TInt KNoThreadId = -1; |
|
153 |
|
154 // a Controllor of whether measure time and write loggs; |
|
155 extern TBool gPerfMeasure; |
|
156 |
|
157 extern TFileName gTestPath; |
|
158 extern TFileName gLogFilePath; |
|
159 |
|
160 // Threads handles |
|
161 extern RArray<RThread> gNotiThreads; |
|
162 extern RThread gFileThread; |
|
163 |
|
164 extern TBuf<50> gLogPostFix; |
|
165 |
|
166 //------------------------------------------------------------- |
|
167 |
|
168 class CTimerLogger; |
|
169 |
|
170 // a wrapper for test settings |
|
171 class TTestSetting |
|
172 { |
|
173 |
|
174 public: |
|
175 TTestSetting(); |
|
176 TTestSetting(TInt aNumFiles, TInt aNumCli, TUint16 aOpt, const TUint* aOpList); |
|
177 inline void Reset(); |
|
178 |
|
179 public: |
|
180 TInt iNumFiles; |
|
181 TInt iNumCli; |
|
182 TUint16 iOption; |
|
183 const TUint* iOperationList; |
|
184 |
|
185 }; |
|
186 |
|
187 // a wrapper of parameters for the main thread to pass into notification thread or file operation thread |
|
188 struct TThreadParam |
|
189 { |
|
190 TTestSetting iSetting; |
|
191 RSemaphore* iSmphFT; // Semophore used by File Thread for waiting for signals from Notification Threads |
|
192 RSemaphore* iSmphNT; // Semophore used by Notification Threads for waiting for signals from File Thread |
|
193 CTimerLogger* iLogger; // Logger used by Notification Threads; |
|
194 RPointerArray<CTimerLogger>* iLoggerArray; // a pointer to an array of pointers to CTimmerLoggger |
|
195 }; |
|
196 |
|
197 // This is the controller of the plugin, it's a simplified copy of the plugin engine used in S60 internally |
|
198 class CMdsPluginControl : public RPlugin |
|
199 { |
|
200 public: |
|
201 inline void RegisterNotification( TMdsFSPStatusPckg& aMdsFSPStatus, TRequestStatus& aStat); |
|
202 inline void AddNotificationPath( const TDesC& aPath ); |
|
203 inline void RemoveNotificationPath( const TDesC& aPath ); |
|
204 inline TInt Enable(); |
|
205 inline TInt Disable(); |
|
206 inline void NotificationCancel(); |
|
207 }; |
|
208 |
|
209 // timer class, also responsible for writing logs |
|
210 class CTimerLogger : public CBase |
|
211 { |
|
212 |
|
213 public: |
|
214 static CTimerLogger* NewL(const TFileName& aLogFile); |
|
215 ~CTimerLogger(); |
|
216 inline TInt MeasureStart(); |
|
217 inline TInt MeasureEnd(); |
|
218 inline TBool Timing(); |
|
219 TInt Log(const TDesC& aDes, TBool aIsLine = ETrue); |
|
220 TInt LogAndPrint(const TDesC& aDes, TBool aIsLine = ETrue); |
|
221 TInt LogSettingDescription(const TInt aNumFile, const TInt aNumCli, const TUint16 aOption, TBool aNumOpVaries = EFalse); |
|
222 TInt LogTestStepTime(TUint aOp, TInt aNum); |
|
223 |
|
224 private: |
|
225 CTimerLogger(); |
|
226 void ConstructL(const TFileName& aLogFile); |
|
227 |
|
228 private: |
|
229 TBool iTiming; |
|
230 TUint32 iTickNumber; |
|
231 TUint iTimeScale; |
|
232 TInt iTickPeriod; |
|
233 TFileName iLogFile; |
|
234 RFs iFs; |
|
235 }; |
|
236 |
|
237 // the conductor of test cases |
|
238 class CTestExecutor : public CBase |
|
239 { |
|
240 |
|
241 public: |
|
242 CTestExecutor(TTestSetting& aSetting); |
|
243 ~CTestExecutor(); |
|
244 |
|
245 inline void SetTestSetting(TTestSetting& aSetting); |
|
246 inline void LogDescription(); |
|
247 |
|
248 void RunTestCaseL(); |
|
249 static void KillAllTestThreads(); |
|
250 |
|
251 private: |
|
252 TTestSetting iTestSetting; |
|
253 |
|
254 }; |
|
255 |
|
256 // This class performs file operations |
|
257 class CFileOperator : public CBase |
|
258 { |
|
259 |
|
260 public: |
|
261 CFileOperator(const TTestSetting& aSetting, RPointerArray<CTimerLogger>& aLoggerArray, RSemaphore* aSmphFT, RSemaphore* aSmphNT); |
|
262 ~CFileOperator(); |
|
263 void DoChangesL(); |
|
264 |
|
265 private: |
|
266 void DoCreateL(); |
|
267 void DoReplaceL(); |
|
268 void DoChangeAttL(); |
|
269 void DoRenameL(); |
|
270 void DoWriteL(); |
|
271 void DoResizeL(); |
|
272 void DoDeleteL(); |
|
273 void DoCreateDirL(); |
|
274 void DoRenameDirL(); |
|
275 void DoDeleteDirL(); |
|
276 void DoMixedOperationsL(); |
|
277 |
|
278 void DoManyChangesOnSingleFileL(); |
|
279 void DoSmallChangesOnManyFilesL(); |
|
280 |
|
281 void MesureStartsAll(); |
|
282 void WaitForSignalsAll(); |
|
283 |
|
284 void TestStepPrepare(TUint aOp); |
|
285 void TestStepFinish(TUint aOp); |
|
286 |
|
287 private: |
|
288 // test case will use the number iFirstFile and iNumFiles to generate test file names. |
|
289 // For example: |
|
290 // if iFirstFile = 0 and iNumFiles = 100, the test files will be 0000.tst, 0001.tst ... 0099.tst |
|
291 // if iFirstFile = 21 and iNumFiles = 200, the test files will be 0021.tst, 0022.tst ... 0220.tst |
|
292 // |
|
293 // When doing rename or replace test, the new names for test will be the biggest existing file |
|
294 // number + 1 to the number + iNumFiles. |
|
295 // As a result, in the case of if iFirstFile = 0 and iNumFiles = 100: |
|
296 // The exsting files should be 0000.tst ... 0099.tst |
|
297 // Rename or Replace test will use the new names 0100.tst ... 0199.tst to replace or rename the |
|
298 // existing files. |
|
299 TInt iFirstFile; |
|
300 |
|
301 // Number of files for operating. |
|
302 // Note: in "Large number changes to a single file" case, this indicates the number of changes made on the single file. |
|
303 TInt iNumFiles; |
|
304 TInt iNumCli; |
|
305 TUint16 iOption; |
|
306 const TUint* iCurrentOp; |
|
307 |
|
308 RPointerArray<CTimerLogger> iLoggers; |
|
309 RSemaphore* iSmphS; // Use for signaling Notification threads |
|
310 RSemaphore* iSmphW; // Use for waiting signal from Notification threads |
|
311 |
|
312 RFs iFs; |
|
313 }; |
|
314 |
|
315 // an operator to monitor notification watcher and test stopper |
|
316 class CNotifyOperator : public CBase |
|
317 { |
|
318 |
|
319 public: |
|
320 CNotifyOperator(const TTestSetting& aSetting, RSemaphore* aSmphFT, RSemaphore* aSmphNT, CTimerLogger* aLogger); |
|
321 ~CNotifyOperator(); |
|
322 |
|
323 void StartOperationL(); |
|
324 |
|
325 private: |
|
326 void LogNotificationNumbers(TInt aNumNoti, TInt aNumIter, TInt aNumOverflow); |
|
327 void LogTestResult(TInt aCounter, TInt aMeanCounter, TInt aOFCounter); |
|
328 void TestChangeReport(TInt aNumChanges); |
|
329 |
|
330 private: |
|
331 TInt iNumFiles; |
|
332 TUint16 iOption; |
|
333 const TUint* iCurrentOp; |
|
334 |
|
335 CTimerLogger* iLogger; |
|
336 RSemaphore* iSmphS; // Use for signaling file operation thread |
|
337 RSemaphore* iSmphW; // Use for waiting signal from file operation thread |
|
338 }; |
|
339 |
|
340 // this class is responsible for handling notifications |
|
341 class CNotifyWatcher : public CActive |
|
342 { |
|
343 friend class CNotifyOperator; |
|
344 |
|
345 public: |
|
346 static CNotifyWatcher* NewL(TInt aNumFiles, TUint16 aOption, TUint aCurrentOp, CTimerLogger* aLogger); |
|
347 ~CNotifyWatcher(); |
|
348 |
|
349 void DoCancel(); |
|
350 void RunL(); |
|
351 |
|
352 void RequestNotification(); |
|
353 |
|
354 void Reset(TUint aOp); |
|
355 |
|
356 private: |
|
357 CNotifyWatcher(TInt aNumFiles, TUint16 aOption, TUint aCurrentOp, CTimerLogger* aLogger); |
|
358 void ConstructL(); |
|
359 |
|
360 void FullDirectoryScanL(RArray<TEntry>& aArray); |
|
361 void MakeChangeRecordL(RArray<TEntry>& aArray); |
|
362 TBool CompareEntry(const TEntry& aEntry1, const TEntry& aEntry2); |
|
363 |
|
364 void AddLotsOfFilters(); |
|
365 |
|
366 void RequestNotificationEnhanced(); |
|
367 void RequestNotificationOriginal(); |
|
368 |
|
369 void HandleNotification(TBool aLastTime); |
|
370 |
|
371 void HandleNotificationEnhanced(TBool aLastTime); |
|
372 void HandleNotificationOriginal(TBool aLastTime); |
|
373 |
|
374 void ResetMdsFSPStatus(); |
|
375 void RequestNotificationPlugin(); |
|
376 void HandleNotificationPlugin(TBool aLastTime); |
|
377 |
|
378 private: |
|
379 TInt iCounter; |
|
380 TInt iMeanCounter; |
|
381 TInt iOverflowCounter; |
|
382 |
|
383 TUint iCurrentOp; |
|
384 TInt iNumFiles; |
|
385 TUint16 iOption; |
|
386 |
|
387 RArray<TEntry> iEntries; |
|
388 RArray<TFileName> iRecords; // this is the output we produce |
|
389 |
|
390 CTimerLogger* iLogger; |
|
391 |
|
392 CFsNotify* iNotify; |
|
393 |
|
394 TMdsFSPStatusPckg iPluginStatusPkg; |
|
395 CMdsPluginControl iPlugin; |
|
396 |
|
397 RFs iFs; |
|
398 }; |
|
399 |
|
400 // An AO aims for stopping the Active Scheduler when test finish |
|
401 class CTestStopper : public CActive |
|
402 { |
|
403 |
|
404 public: |
|
405 CTestStopper(); |
|
406 ~CTestStopper(); |
|
407 |
|
408 void DoCancel(); |
|
409 void RunL(); |
|
410 |
|
411 void StartWaitingForFile(); |
|
412 |
|
413 private: |
|
414 TFileName iTestEndFile; |
|
415 RFs iFs; |
|
416 }; |
|
417 |
|
418 #include "t_notify_perf.inl" |