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 // e32test\bench\t_proc1.cpp
15 // One half of the process relative type test stuff
17 // Tests the RProcess class, including tests on the heap, process naming,
18 // process resumption, process creation and shared chunks.
22 // - Open a nonexistent process by a process Id and checks for the failure
23 // of finding this process.
24 // - Open a process with invalid name and verify failure results are as expected.
25 // - Test the closing of processes by calling Kill, Terminate, and Panic methods.
26 // Verify results are as expected.
27 // - Create a process and verify the full path name of the loaded executable on
28 // which this process is based.
29 // - Open a process by name, rename the process in a variety of ways and verify
30 // the results are as expected.
31 // - Open a process, assign high, low, and bad priorities, verify the results
33 // - Open a process, kill it and verify the results are as expected.
34 // - Open a process by name based on the file name, verify the results are as
36 // - Retrieve the process Id and open a handle on it. Create a duplicate process.
37 // Verify the results are as expected.
38 // - Find a process using TFindProcess() and open a handle on it. Verify the
39 // results are as expected.
40 // - Check chunk sharing between threads and verify results are as expected.
41 // - Perform a "speed" test where a new thread is created and the thread increments
42 // a count until stopped. Calculate and display counts per second. Verify results
44 // - Verify the ExitReason, ExitType and ExitCatagory when the thread dies.
45 // - Verify that stopping the process completes existing pending requests with
46 // KErrServerTerminated.
47 // - Verify that the heap was not corrupted by the tests.
48 // Platforms/Drives/Compatibility:
50 // Assumptions/Requirement/Pre-requisites:
51 // Failures and causes:
52 // Base Port information:
57 #include "../mmu/mmudetect.h"
60 LOCAL_D RTest test(_L("T_PROC1"));
62 const TBufC<67> tooLong=_L("This should return KErrBadName and not crash.......0123456789ABCDEF");
63 const TBufC<66> notQuiteTooLong=_L("This should return KErrNone and be completely OK..0123456789ABCDEF");
64 const TBufC<26> bond=_L("Bond, James Bond[00000000]");
65 const TBufC<16> jamesBond=_L("Bond, James Bond");
73 TRequestStatus stat,notStat;
75 const TInt KKillReason=2563453;
76 const TInt KTerminateReason=8034255;
77 const TInt KPanicReason=39365235;
79 LOCAL_D RSemaphore client;
80 LOCAL_D TInt speedCount;
82 class RDisplay : public RSessionBase
86 TInt Display(const TDesC& aMessage);
100 return(CreateSession(_L("Display"),Version(),1));
103 TInt RDisplay::Display(const TDesC& aMessage)
105 // Display a message.
109 TBuf<0x10> b(aMessage);
110 return(SendReceive(CMyServer::EDisplay,TIpcArgs(&b)));
113 TInt RDisplay::Read()
115 // Get session to test CSession2::ReadL.
119 TBuf<0x10> b(_L("Testing read"));
120 return(SendReceive(CMyServer::ERead,TIpcArgs(&b)));
123 TInt RDisplay::Write()
125 // Get session to test CSession2::WriteL.
130 TBufC<0x10> c; // Bad descriptor - read only
131 TInt r=SendReceive(CMyServer::EWrite,TIpcArgs(&b,&c));
132 if (r==KErrNone && b!=_L("It worked!"))
137 TInt RDisplay::Test()
139 // Send a message and wait for completion.
144 return(SendReceive(CMyServer::ETest,TIpcArgs(&i[0])));
147 TInt RDisplay::Stop()
154 return(SendReceive(CMyServer::EStop,TIpcArgs(&i[0])));
157 TVersion RDisplay::Version()
159 // Return the current version.
163 TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
167 LOCAL_C TInt RunPanicThread(RThread& aThread)
171 TBool jit = User::JustInTime();
172 User::SetJustInTime(EFalse);
174 User::WaitForRequest(s);
175 User::SetJustInTime(jit);
179 TInt KillProtectedEntry(TAny*)
181 proc.Kill(KErrGeneral);
185 TInt createProc2(RProcess& aProcess)
187 TFileName filename(RProcess().FileName());
188 TInt pos=filename.LocateReverse(TChar('\\'));
189 filename.SetLength(pos+1);
190 filename+=_L("T_PROC2.EXE");
191 TInt r=aProcess.Create(filename, command);
194 TFullName fn(aProcess.FullName());
195 test.Printf(_L("Created %S\n"),&fn);
202 test.Next(_L("Open by name"));
204 TInt r=proc2.Open(me.Name());
206 test.Next(_L("Rename"));
207 TName initName(me.Name());
208 r=User::RenameProcess(jamesBond);
210 test(me.Name().Left(26)==bond);
211 test(proc2.Name().Left(26)==bond);
212 r=User::RenameProcess(tooLong);
213 test(r==KErrBadName);
214 test(me.Name().Left(26)==bond);
215 test(proc2.Name().Left(26)==bond);
216 TName* work=new TName(notQuiteTooLong);
217 r=User::RenameProcess(*work);
219 work->Append(_L("[00000000]"));
220 test(me.Name().Length()==KMaxKernelName);
221 test(me.Name().Left(KMaxKernelName-4)==*work);
222 test(proc2.Name().Length()==KMaxKernelName);
223 test(proc2.Name().Left(KMaxKernelName-4)==*work);
225 r=User::RenameProcess(_L("T_PROC1"));
227 TFullName fn(_L("T_PROC1["));
228 TUidType uidType(me.Type());
229 TUint32 uid3 = uidType[2].iUid;
230 fn.AppendNumFixedWidth(uid3,EHex,8);
232 test(proc2.Name().Left(17)==fn);
233 test(me.Name().Left(17)==fn);
234 TInt l = initName.Locate('[');
235 r=User::RenameProcess(initName.Left(l));
237 test(proc2.Name()==initName);
241 TInt BadPriority(TAny* proc2)
243 ((RProcess*)proc2)->SetPriority(EPriorityWindowServer);
249 TInt r=proc2.Open(proc.Name());
250 test.Next(_L("Mess with Priority"));
251 proc.SetPriority(EPriorityHigh);
252 test.Printf(_L("%d %d\n"),proc.Priority(),proc2.Priority());
253 test(proc.Priority()==EPriorityHigh);
254 test(proc2.Priority()==EPriorityHigh);
255 proc2.SetPriority(EPriorityLow);
256 test(proc.Priority()==EPriorityLow);
257 test(proc2.Priority()==EPriorityLow);
260 r=thread.Create(_L("Bad Priority"),BadPriority,KDefaultStackSize,NULL,&proc2);
262 r=RunPanicThread(thread);
263 test(r==EBadPriority);
264 test(thread.ExitType()==EExitPanic);
265 test(thread.ExitReason()==EBadPriority);
266 test(thread.ExitCategory()==_L("KERN-EXEC"));
267 CLOSE_AND_WAIT(thread);
268 test(proc.Priority()==EPriorityLow);
269 test(proc2.Priority()==EPriorityLow);
275 test.Next(_L("Test functions"));
276 TFileName fileName(proc.FileName());
277 test.Printf(fileName);
279 if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
280 test(fileName.Mid(1).CompareF(_L(":\\Sys\\Bin\\T_PROC2.EXE"))==0);
282 test(fileName.Mid(1).CompareF(_L(":\\System\\Bin\\T_PROC2.EXE"))==0);
284 if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
285 test(fileName.CompareF(_L("Z:\\Sys\\Bin\\T_PROC2.EXE"))==0);
287 test(fileName.CompareF(_L("Z:\\System\\Bin\\T_PROC2.EXE"))==0);
289 test(proc.Name().Left(21).CompareF(_L("T_PROC2.EXE[00000000]"))==0);
290 test(proc.Priority()==EPriorityForeground);
291 test(proc.ExitType()==EExitPending);
292 test(proc.ExitReason()==0);
293 test(proc.ExitCategory()==KNullDesC);
298 test.Next(_L("Kill and recreate"));
300 TInt r=proc2.Open(proc.Id());
302 test(proc2.Handle()!=0);
305 r=proc.LogonCancel(notStat);
307 test(notStat==KErrNone);
308 proc.Kill(KKillReason);
309 User::WaitForRequest(stat);
310 test(stat==KKillReason);
311 test(proc.ExitType()==EExitKill);
312 test(proc.ExitReason()==KKillReason);
313 test(proc.ExitCategory()==_L("Kill"));
315 test(proc.Handle()==0);
316 test(proc2.ExitType()==EExitKill);
317 test(proc2.ExitReason()==KKillReason);
318 test(proc2.ExitCategory()==_L("Kill"));
319 CLOSE_AND_WAIT(proc2);
320 test(proc2.Handle()==0);
325 TFileName filename(RProcess().FileName());
326 TInt pos=filename.LocateReverse(TChar('\\'));
327 filename.SetLength(pos+1);
328 filename+=_L("T_PROC2.EXE");
329 TInt r=proc.Create(filename, command);
331 TFullName fn(proc.FullName());
332 test.Printf(_L("Created %S\n"),&fn);
333 test(proc.FileName().CompareF(filename)==0);
334 test(proc.Name().Left(21).CompareF(_L("T_PROC2.EXE[00000000]"))==0);
335 test(proc.Priority()==EPriorityForeground);
336 test(proc.ExitType()==EExitPending);
337 test(proc.ExitReason()==0);
338 test(proc.ExitCategory()==KNullDesC);
343 test.Next(_L("Get and open by Id"));
344 TProcessId id=proc.Id();
345 TProcessId id2=proc.Id();
347 TInt r=proc2.Open(proc.Name());
358 test.Next(_L("Create duplicate"));
359 r=createProc2(proc3);
363 test(*(TUint*)&id<*(TUint*)&id2);
369 test.Next(_L("Try to find processes"));
370 TFindProcess* findProc=new TFindProcess(_L("T_PROC2*"));
371 test(findProc!=NULL);
372 TFullName* result=new TFullName;
374 TInt r=findProc->Next(*result);
376 TFullName temp = proc.FullName();
377 test(result->CompareF(temp)==0);
378 r=findProc->Next(*result);
380 test(result->CompareF(proc3.FullName())==0);
381 r=findProc->Next(*result);
382 test(r==KErrNotFound);
383 findProc->Find(_L("T?PROC2*]*"));
384 r=findProc->Next(*result);
386 test(result->CompareF(temp)==0);
387 r=findProc->Next(*result);
389 test(result->CompareF(proc3.FullName())==0);
391 test.Next(_L("Open by find handle"));
392 r=proc4.Open(*findProc);
394 TProcessId id=proc3.Id();
395 TProcessId id2=proc4.Id();
402 test.Next(_L("Kill duplicate"));
404 test(stat==KRequestPending);
406 User::WaitForRequest(stat);
412 // Create T_PROC2 and, on the way, do lots of basic tests
415 test.Start(_L("Create"));
416 TInt r=globSem1.CreateGlobal(_L("GlobSem1"), 0);
418 r=globSem2.CreateGlobal(_L("GlobSem2"), 0);
441 CLOSE_AND_WAIT(proc4);
443 test.Next(_L("Resume"));
444 proc.Logon(stat); // logon to process
446 r=proc.LogonCancel(notStat);
448 test(notStat==KErrNone);
449 test(proc.ExitType()==EExitPending);
451 globSem1.Wait(); // wait for T_PROC2 to get started
457 test.Start(_L("Kill"));
459 TInt r=createProc2(process);
461 TProcessId id=process.Id();
462 TProcessId id2=process.Id();
466 test(process.ExitType()==EExitPending);
467 process.Kill(KKillReason);
468 User::WaitForRequest(stat);
469 test(stat==KKillReason);
470 test(process.ExitType()==EExitKill);
471 test(process.ExitReason()==KKillReason);
472 test(process.ExitCategory()==_L("Kill"));
473 CLOSE_AND_WAIT(process);
475 test.Next(_L("Terminate"));
476 r=createProc2(process);
479 test(*(TUint*)&id+2==*(TUint*)&id2); // use 2 ID's each time, one for process, one for thread
481 test(process.ExitType()==EExitPending);
482 process.Terminate(KTerminateReason);
483 User::WaitForRequest(stat);
484 test(stat==KTerminateReason);
485 test(process.ExitType()==EExitTerminate);
486 test(process.ExitReason()==KTerminateReason);
487 test(process.ExitCategory()==_L("Terminate"));
488 CLOSE_AND_WAIT(process);
490 test.Next(_L("Panic"));
491 r=createProc2(process);
494 test(*(TUint*)&id+4==*(TUint*)&id2);
495 test(process.ExitType()==EExitPending);
497 process.SetJustInTime(EFalse); // prevent the process panic from starting the debugger
498 process.Panic(_L("BOO!"),KPanicReason);
499 User::WaitForRequest(stat);
500 test(stat==KPanicReason);
501 test(process.ExitType()==EExitPanic);
502 test(process.ExitReason()==KPanicReason);
503 test(process.ExitCategory()==_L("BOO!"));
504 CLOSE_AND_WAIT(process);
510 test.Start(_L("Test chunk sharing between threads"));
512 test.Next(_L("Create chunk Marmalade"));
517 r=chunk.CreateGlobal(_L("Marmalade"),size,maxSize);
519 test.Next(_L("Write 0-9 to it"));
520 TUint8* base=chunk.Base();
521 for (TInt8 j=0;j<10;j++)
522 *base++=j; // write 0 - 9 to the chunk
523 globSem2.Signal(); // T_PROC2 can check the chunk now
525 chunk.Close(); // now it's ok to kill the chunk
530 TInt sharedChunks2(TAny* /*aDummy*/)
532 RTest test(_L("Shared Chunks 2"));
535 test.Start(_L("Test chunk sharing between threads"));
537 test.Next(_L("Create chunk Marmalade"));
542 r=chunk.CreateGlobal(_L("Marmalade"),size,maxSize);
544 test.Next(_L("Write 0-9 to it"));
545 TUint8* base=chunk.Base();
546 for (TInt8 j=0;j<10;j++)
547 *base++=j; // write 0 - 9 to the chunk
548 globSem2.Signal(); // T_PROC2 can check the chunk now
550 chunk.Close(); // now it's ok to kill the chunk
556 TInt speedyThreadEntryPoint(TAny*)
558 // The entry point for the speed test thread.
566 while ((r=t.Test())==KErrNone)
578 TInt sharedHeap(TAny*)
580 RTest test2(_L("sharedHeap"));
582 test2.Start(_L("Shared heap tests"));
584 RAllocator* allocator = &User::Allocator();
585 test2.Printf(_L("sharedHeap's heap is at %08x\n"), allocator);
588 allocator->AllocSize(size);
589 test2.Printf(_L("sharedHeap's heap allocsize is %08x\n"),size);
591 // Press a key only if running the test in manual mode. We will be
592 // able to ascertain this when RTest has been enhanced.
593 // test.Next(_L("Press a key to continue"));
600 _LIT(KTestProcessNewName,"T_PROC1_NEW.EXE");
602 TInt DupRenameProcTest(TInt aCall)
604 test.Printf(_L("DupRenameProcTest: call %d\n"),aCall);
612 r = User::RenameProcess(KTestProcessNewName);
614 TFullName fn(RProcess().FullName());
615 test.Printf(_L("Renamed to %S\n"),&fn);
616 TInt li = fn.Locate('[');
617 TInt ri = fn.Locate(']');
618 test(fn.Left(li)==KTestProcessNewName);
619 test(fn.Mid(ri+1)==_L("0001"));
624 TFileName filename(RProcess().FileName());
625 TInt pos=filename.LocateReverse(TChar('\\'));
626 filename.SetLength(pos+1);
627 filename+=_L("T_PROC1.EXE");
631 r = pr.Create(filename, call);
632 TFullName fn(pr.FullName());
633 test.Printf(_L("Created %S\n"),&fn);
637 User::WaitForRequest(st);
644 r = User::RenameProcess(KTestProcessNewName);
646 TFullName fn(RProcess().FullName());
647 test.Printf(_L("Renamed to %S\n"),&fn);
648 TInt li = fn.Locate('[');
649 TInt ri = fn.Locate(']');
650 test(fn.Left(li)==KTestProcessNewName);
651 test(fn.Mid(ri+1)==_L("0002"));
660 _LIT(KTestProcessName,"TestName");
662 void TestProcessRename()
664 // Rename the current process with test name
665 TInt r = User::RenameProcess(KTestProcessName);
667 TName name1 = RProcess().Name();
669 // Check new name is correct
671 name2.SetLength(KTestProcessName().Length());
672 test(name2.CompareF(KTestProcessName)==0);
674 // Rename the process with same test name
675 r = User::RenameProcess(KTestProcessName);
677 name2 = RProcess().Name();
678 test(name1.Compare(name2)==0); // name should be unchanged
685 // Turn off lazy dll unloading
687 test(l.Connect()==KErrNone);
688 test(l.CancelLazyDllUnload()==KErrNone);
692 User::CommandLine(cmd);
693 if(cmd.Length() && TChar(cmd[0]).IsDigit())
695 TInt r = DupRenameProcTest(TUint(TChar(cmd[0])) - '0');
702 test.Start(_L("Testing process stuff 1"));
705 test.Next(_L("Creating semaphore"));
706 r=client.CreateLocal(0);
709 test.Next(_L("Try to open nonexistant process by ID"));
710 r=proc.Open(*(TProcessId*)&KMaxTUint);
711 test(r==KErrNotFound);
713 test.Next(_L("Try to open process with invalid name"));
715 r=thread.Create(_L("Bad Name"),BadName,KDefaultStackSize,NULL,NULL);
717 TRequestStatus threadStat;
718 thread.Logon(threadStat);
719 TBool justInTime=User::JustInTime();
720 User::SetJustInTime(EFalse);
722 User::WaitForRequest(threadStat);
723 User::SetJustInTime(justInTime);
724 test(threadStat==EBadName);
725 test(thread.ExitType()==EExitPanic);
726 test(thread.ExitReason()==EBadName);
727 test(thread.ExitCategory()==_L("KERN-EXEC"));
728 CLOSE_AND_WAIT(thread);
730 test.Next(_L("Murder processes in different ways"));
733 test.Next(_L("Create second process"));
736 test.Next(_L("Shared Chunks from main thread"));
739 test.Next(_L("Shared chunks from secondary thread"));
741 r=t.Create(_L("Shared chunks 2"),sharedChunks2,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
745 User::WaitForRequest(s);
749 test.Next(_L("Starting speedy client"));
751 r=speedy.Create(_L("Speedy"),speedyThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
754 RThread().SetPriority(EPriorityMuchMore);
755 speedy.SetPriority(EPriorityNormal);
756 TRequestStatus speedyStatus;
757 speedy.Logon(speedyStatus);
760 test.Next(_L("Wait for speedy to start"));
763 globSem1.Wait(); // wait for proc2 to be nice & quiet
764 test.Printf(_L("Starting speed test...\n"));
767 User::After(3000000);
769 test.Printf(_L("Count = %d in 1 second\n"),(n-b)/3);
771 test.Next(_L("Tell second process speed tests are done"));
774 test.Next(_L("Process Logon"));
775 User::WaitForRequest(stat);
776 const TDesC& cat=proc.ExitCategory();
777 test.Printf(_L("Exit category = %S\n"),&cat);
778 test.Printf(_L("Exit reason = %x\n"),proc.ExitReason());
779 test.Printf(_L("Exit type = %x\n"),proc.ExitType());
781 test(stat==KErrNone);
782 test(proc.ExitCategory()==_L("Kill"));
783 test(proc.ExitReason()==KErrNone);
784 test(proc.ExitType()==EExitKill);
785 test(notStat==KErrNone);
786 test.Next(_L("Test LogonCancel to dead process is ok"));
787 r=proc.LogonCancel(stat);
788 test(r==KErrGeneral);
793 User::WaitForRequest(speedyStatus);
794 test(speedyStatus==KErrServerTerminated);
795 test(speedy.ExitReason()==KErrServerTerminated);
796 test(speedy.ExitType()==EExitKill);
797 CLOSE_AND_WAIT(speedy);
798 CLOSE_AND_WAIT(proc);
800 User::After(5000000); // wait for MMC session to disappear
802 test.Next(_L("Test rename of the processes with duplicate names"));
803 r = DupRenameProcTest(0);
808 test.Next(_L("Check for kernel alloc heaven"));