Update contrib.
1 // Copyright (c) 1996-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32test\server\t_open.cpp
22 GLDEF_D RTest test(_L("T_OPEN"));
24 LOCAL_D TFileName gBatchFile;
25 LOCAL_D TBool gRunByBatch=EFalse;
27 TFileName filename1=_L("Z:\\TEST\\T_FSRV.CPP");
28 TFileName filename2=_L("Z:\\TEST\\T_FILE.CPP");
29 TFileName dirname1=_L("Z:\\TEST\\*.XDE");
34 // Scan for open files - no sessions
38 test.Next(_L("Scan for open files with no sessions open"));
40 TOpenFileScan fileScan(TheFs);
44 TInt count=list->Count();
48 gBatchFile=(*list)[0].iName;
57 TEntry entry=(*list)[count];
58 test.Printf(_L("%d) EntryName = %S\n"),count,&entry.iName);
60 test.Printf(_L("Test will fail unless files are closed.\n"));
62 //test.Printf(_L("Press any key ...\n"));
72 test.Next(_L("Scan for open files - one session only"));
74 RFile file1,file2,file3;
76 TInt r=file1.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly);
79 r=file2.Open(TheFs,filename2,EFileRead);
82 r=file3.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly);
86 TOpenFileScan fileScan(TheFs);
87 TRAP(r,fileScan.NextL(list));
93 test(list->Count()==1);
94 TEntry entry=(*list)[0];
95 test(entry.iName.FindF(_L(".BAT"))>=0);
102 TInt count=list->Count();
104 TEntry entry=(*list)[0];
106 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
108 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
110 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
111 TThreadId threadId=fileScan.ThreadId();
113 TThreadId currentId=current.Id();
114 test(threadId==currentId);
117 fileScan.NextL(list);
127 // Test openfilescan - empty, full, empty.
132 test.Next(_L("Scan for open files - empty sessions"));
135 TInt r=fs1.Connect();
144 RFile file1,file2,file3;
146 r=file1.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
149 r=file2.Open(fs2,filename2,EFileRead);
152 r=file3.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
156 TOpenFileScan fileScan(TheFs);
157 fileScan.NextL(list);
162 test(list->Count()==1);
163 TEntry entry=(*list)[0];
164 test(entry.iName.FindF(_L(".BAT"))>=0);
166 fileScan.NextL(list);
170 TInt count=list->Count();
172 TEntry entry=(*list)[0];
173 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
175 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
177 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
178 TThreadId threadId=fileScan.ThreadId();
180 TThreadId currentId=current.Id();
181 test(threadId==currentId);
184 fileScan.NextL(list);
198 // Test openfilescan - empty, full, empty full
202 test.Next(_L("Scan for open files - multiple sessions"));
205 TInt r=fs1.Connect();
214 RFile file1,file2,file3;
216 r=file1.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
219 r=file2.Open(fs2,filename2,EFileRead|EFileShareReadersOnly);
222 r=file3.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
225 r=file1.Open(fs4,filename1,EFileRead|EFileShareReadersOnly);
228 r=file2.Open(fs4,filename2,EFileRead|EFileShareReadersOnly);
231 r=file3.Open(fs4,filename1,EFileRead|EFileShareReadersOnly);
235 TOpenFileScan fileScan(TheFs);
236 fileScan.NextL(list);
241 test(list->Count()==1);
242 TEntry entry=(*list)[0];
243 test(entry.iName.FindF(_L(".BAT"))>=0);
245 fileScan.NextL(list);
249 TInt count=list->Count();
251 TEntry entry=(*list)[0];
252 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
254 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
256 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
257 TThreadId threadId=fileScan.ThreadId();
259 TThreadId currentId=current.Id();
260 test(threadId==currentId);
263 fileScan.NextL(list);
268 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
270 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
272 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
273 threadId=fileScan.ThreadId();
274 currentId=current.Id();
275 test(threadId==currentId);
278 fileScan.NextL(list);
292 // Test openfilescan - rdirs, empty, full, empty rdirs.
295 test.Next(_L("Scan for open files - check RDir sessions are ignored"));
298 TInt r=fs1.Connect();
307 RDir dir1,dir2,dir3,dir4;
308 r=dir1.Open(TheFs,dirname1,KEntryAttMaskSupported);
310 r=dir2.Open(TheFs,dirname1,KEntryAttMaskSupported);
312 r=dir3.Open(TheFs,dirname1,KEntryAttMaskSupported);
314 r=dir4.Open(TheFs,dirname1,KEntryAttMaskSupported);
317 RFile file1,file2,file3;
318 r=file1.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
320 r=file2.Open(fs2,filename2,EFileRead);
322 r=file3.Open(fs2,filename1,EFileRead|EFileShareReadersOnly);
325 RDir dir5,dir6,dir7,dir8;
326 r=dir5.Open(fs4,dirname1,KEntryAttMaskSupported);
328 r=dir6.Open(fs4,dirname1,KEntryAttMaskSupported);
330 r=dir7.Open(fs4,dirname1,KEntryAttMaskSupported);
332 r=dir8.Open(fs4,dirname1,KEntryAttMaskSupported);
336 TOpenFileScan fileScan(TheFs);
337 fileScan.NextL(list);
342 test(list->Count()==1);
343 TEntry entry=(*list)[0];
344 test(entry.iName.FindF(_L(".BAT"))>=0);
346 fileScan.NextL(list);
350 TInt count=list->Count();
352 TEntry entry=(*list)[0];
353 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
355 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
357 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
358 TThreadId threadId=fileScan.ThreadId();
360 TThreadId currentId=current.Id();
361 test(threadId==currentId);
364 fileScan.NextL(list);
370 dir1.Close(); dir2.Close();
371 dir3.Close(); dir4.Close();
372 dir5.Close(); dir6.Close();
373 dir7.Close(); dir8.Close();
374 fs1.Close(); fs2.Close();
375 fs3.Close(); fs4.Close();
384 test.Next(_L("Scan for open files - mixed RDirs and RFiles"));
386 RFile file1,file2,file3;
387 TInt r=file1.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly);
389 r=file2.Open(TheFs,filename2,EFileRead);
391 r=file3.Open(TheFs,filename1,EFileRead|EFileShareReadersOnly);
394 RDir dir1,dir2,dir3,dir4;
395 r=dir1.Open(TheFs,dirname1,KEntryAttMaskSupported);
397 r=dir2.Open(TheFs,dirname1,KEntryAttMaskSupported);
399 r=dir3.Open(TheFs,dirname1,KEntryAttMaskSupported);
401 r=dir4.Open(TheFs,dirname1,KEntryAttMaskSupported);
405 TOpenFileScan fileScan(TheFs);
406 fileScan.NextL(list);
411 test(list->Count()==1);
412 TEntry entry=(*list)[0];
413 test(entry.iName.FindF(_L(".BAT"))>=0);
415 fileScan.NextL(list);
419 TInt count=list->Count();
421 TEntry entry=(*list)[0];
422 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
424 test(entry.iName.FindF(_L("T_FILE.CPP"))>=0);
426 test(entry.iName.FindF(_L("T_FSRV.CPP"))>=0);
427 TThreadId threadId=fileScan.ThreadId();
429 TThreadId currentId=current.Id();
430 test(threadId==currentId);
433 fileScan.NextL(list);
446 NONSHARABLE_STRUCT(TThreadData)
448 // Encapsulates the data required by the worker thread.
451 // Thread identifier for debug output
454 // ID of the thread that started the worker thread, and the
455 // worker thread itself
459 // Request status object of the parent thread, used for signalling
460 TRequestStatus* iStatus;
462 // Name of the file the parent thread requires this thread to open
465 // Number of files opened by the thread;
470 LOCAL_C TInt WorkerThread(TAny* aParameter)
472 // This function is designed to run as a separate thread in order to verify the
473 // fix for DEF062875.
475 // When the thread is started it opens the file specified in the startup
476 // parameter, signals the main thread and then suspends. Once the main thread
477 // has completed its checking the worker thread is resumed and allowed to run
480 // @param aParameter Thread specific data supplied by the main thread when the
481 // worker thread is started. The data may be accessed by
482 // casting this pointer to a TThreadData*
485 // Can't use our global "test" object here
486 RTest myTest(_L("Worker thread"));
489 // Extract the parameters that this thread will need to use
490 TThreadData* threadData = (TThreadData*)aParameter;
494 TThreadId currentId = current.Id();
497 myTest.Printf(_L("WORK%d: Worker thread %d started\n"), threadData->iNumber, threadData->iNumber);
498 myTest.Printf(_L("WORK%d: File: %S\n"), threadData->iNumber, &threadData->iFilename);
499 myTest.Printf(_L("WORK%d: Thread: %d\n"), threadData->iNumber, (TUint)currentId);
500 myTest.Printf(_L("WORK%d: Parent: %d\n"), threadData->iNumber, (TUint)threadData->iMain);
503 // Open the file specified by the parameter passed to us from the main
508 User::LeaveIfError(file.Open(myFs, threadData->iFilename, EFileRead | EFileShareReadersOnly));
510 // Signal the parent thread to continue then wait
511 myTest.Printf(_L("WORK%d: Signalling parent thread\n"), threadData->iNumber);
513 User::LeaveIfError(parent.Open(threadData->iMain));
514 parent.RequestComplete(threadData->iStatus, KErrNone);
517 myTest.Printf(_L("WORK%d: Waiting for parent thread to restart us\n"), threadData->iNumber);
522 myTest.Printf(_L("WORK%d: Closing file\n"), threadData->iNumber);
530 LOCAL_C void TestDEF062875()
532 // Verify that TOpenFileScan::ThreadId() returns the ID of the thread that
535 // The object of the exercise here is to create several worker threads, each
536 // one will open a file, signal the main thread and then suspend. Once all
537 // the worker threads have suspended the main thread then uses
538 // TOpenFileScan::NextL() to verify that the thread IDs correspond to the
539 // worker threads that opened each file and not that of the main thread.
541 // The worker threads are then restarted and allowed to terminate naturally by
542 // running to completion
545 test.Start(_L("Test TOpenFileScan::ThreadId()"));
547 const TInt KHeapSize = 32768;
552 TRequestStatus status1;
553 TRequestStatus status2;
555 TThreadId id = RThread().Id();
557 TThreadData threadData[3];
559 threadData[0].iNumber = 0;
560 threadData[0].iMain = id;
561 threadData[0].iWorker = id;
562 threadData[0].iStatus = 0;
563 threadData[0].iFilename = filename1;
564 threadData[0].iNumFiles = 2;
566 threadData[1].iNumber = 1;
567 threadData[1].iMain = id;
568 threadData[1].iStatus = &status1;
569 threadData[1].iFilename = filename1;
570 threadData[1].iNumFiles = 1;
572 threadData[2].iNumber = 2;
573 threadData[2].iMain = id;
574 threadData[2].iStatus = &status2;
575 threadData[2].iFilename = filename2;
576 threadData[2].iNumFiles = 1;
578 TInt numThreads = sizeof(threadData)/sizeof(threadData[0]);
581 // Open the files in the MAIN thread.
583 User::LeaveIfError(file1.Open(TheFs, filename1, EFileRead | EFileShareReadersOnly));
586 User::LeaveIfError(file2.Open(TheFs, filename2, EFileRead | EFileShareReadersOnly));
589 // Create the first worker thread
590 test.Printf(_L("MAIN: Creating worker threads\n"));
591 thread1.Create(_L("WorkerThread1"), WorkerThread, KDefaultStackSize, KHeapSize, KHeapSize, &threadData[1]);
592 threadData[1].iWorker = thread1.Id();
594 // Start it and wait for it to suspend
595 thread1.Logon(status1);
597 test.Printf(_L("MAIN: Waiting for worker thread 1\n"));
598 User::WaitForRequest(status1);
601 // Create the second worker thread
602 thread2.Create(_L("WorkerThread2"), WorkerThread, KDefaultStackSize, KHeapSize, KHeapSize, &threadData[2]);
603 threadData[2].iWorker = thread2.Id();
606 // Start it and wait for it to suspend
607 thread2.Logon(status2);
609 test.Printf(_L("MAIN: Waiting for worker thread 2\n"));
610 User::WaitForRequest(status2);
613 // Obtain a list of open files. At this point we should have a single open
614 // file, as opened by our worker thread. The thread ID reported by
615 // TOpenFileScan should be that of our worker thread rather than the main
617 test.Printf(_L("MAIN: Verifying thread ID of open file(s)\n"));
619 TOpenFileScan fileScan(TheFs);
625 fileScan.NextL(list);
628 // The NULL list indicates we've run out of sessions.
635 TThreadId threadId=fileScan.ThreadId();
636 TThreadData* data = 0;
637 for (count = 0; count < numThreads; count++)
639 if (threadId == threadData[count].iWorker)
641 data = &threadData[count];
649 test.Next(_L("Check number of open files..."));
650 test.Printf(_L("MAIN: Number of open files: %d (expecting %d)\n"), list->Count(), data->iNumFiles);
651 test(list->Count() == threadData[count].iNumFiles);
654 test.Next(_L("Check TThreadIds..."));
655 test.Printf(_L("MAIN: Main thread ID : %d\n"), (TUint)data->iMain);
656 test.Printf(_L("MAIN: Worker thread ID: %d\n"), (TUint)data->iWorker);
657 test.Printf(_L("MAIN: File thread ID : %d\n"), (TUint)threadId);
661 for (loop = 0; loop < list->Count(); loop++)
663 const TEntry& theEntry = (*list)[loop];
664 test.Printf(_L(" "));
665 test.Printf(theEntry.iName);
666 test.Printf(_L("\n"));
671 test.Printf(_L("Ignored thread %d\n"), (TUint)threadId);
679 test.Printf(_L("\n"));
683 // Signal the two worker threads to tidy up and run to normal termination
684 test.Printf(_L("MAIN: Signalling worker thread 1\n"));
685 thread1.Logon(status1);
687 User::WaitForRequest(status1);
689 test.Printf(_L("MAIN: Signalling worker thread 2\n"));
690 thread2.Logon(status2);
692 User::WaitForRequest(status2);
695 // Tidy up and finish
696 test.Printf(_L("MAIN: Closing worker thread 1\n"));
699 test.Printf(_L("MAIN: Closing worker thread 2\n"));
709 GLDEF_C void CallTestsL()
711 // Call tests that may leave
714 filename1[0] = gExeFileName[0];
715 filename2[0] = gExeFileName[0];
716 dirname1[0] = gExeFileName[0];