Update contrib.
1 // Copyright (c) 1995-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_svr.cpp
16 // Tests and benchmarks the Client/Server architecture of the Symbian platform.
17 // The client and server run in different threads in the same process.
19 // CSession2, CServer2, RSessionBase.
21 // - Create and start a server thread. Verify results are as expected.
22 // - Open a connection with the server, verify arguments are passed to the server
23 // and back correctly.
24 // - Server can read and write messages to/from the client and return verify that
25 // the results are as expected.
26 // - Send dummy messages that the server completes immediately and display how many
27 // are completed per second.
28 // - Stop the server and verify the results are as expected.
29 // - Verify that the kernel does not crash by completing a message with an invalid
30 // handle and verify the client is panicked with EBadMessageHandle.
31 // Platforms/Drives/Compatibility:
33 // Assumptions/Requirement/Pre-requisites:
34 // Failures and causes:
35 // Base Port information:
39 #define __E32TEST_EXTENSION__
42 #include <e32base_private.h>
48 #include "../mmu/mmudetect.h"
50 const TInt KHeapSize=0x2000;
51 const TInt KMajorVersionNumber=1;
52 const TInt KMinorVersionNumber=0;
53 const TInt KBuildVersionNumber=1;
55 _LIT(KServerName,"Display");
57 _LIT(KReadDesContents, "Testing read");
58 _LIT(KLengthDesContents, "What-ever");
59 _LIT(KWriteDesContents, "It worked!");
60 _LIT(KLocalWriteDesContents, "Local write");
67 ESpeedGetMaxDesLength,
72 _LIT(KTestNameNull, "Null");
73 _LIT(KTestNameUnusedDes, "UnusedDes");
74 _LIT(KTestNameGetDesLength, "GetDesLength");
75 _LIT(KTestNameGetMaxDesLength, "GetMaxDesLength");
76 _LIT(KTestNameReadDes, "ReadDes");
77 _LIT(KTestNameWriteDes, "WriteDes");
79 _LIT(KLitLocal, "Local");
80 _LIT(KLitRemote, "Remote");
82 const TDesC* KSpeedTestNames[] =
86 &KTestNameGetDesLength,
87 &KTestNameGetMaxDesLength,
92 class CMySession : public CSession2
97 void DisplayName(const RMessage2& aM);
98 virtual void ServiceL(const RMessage2& aMessage); //pure virtual fns.
100 RArray<RMessagePtr2> iAsyncRequests;
103 class CMyServer : public CServer2
106 enum {EDisplay,ERead,EGetDesLength,EGetDesMaxLength,EWrite,ELocalWrite,EDupDes,ENull,ESimpleRead,ESimpleWrite,EStartAsync,ECompleteAsync,EStop};
108 CMyServer(TInt aPriority);
109 static CMyServer* New(TInt aPriority);
110 virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;//Overloading
113 class CMyActiveScheduler : public CActiveScheduler
116 virtual void Error(TInt anError) const; //Overloading pure virtual function
119 class RDisplay : public RSessionBase
122 TInt Open(TInt aMessageSlots=0);
123 TInt Display(const TDesC& aMessage);
124 TInt Read(TInt aArgIndex);
125 TInt Write(TInt aArgIndex);
126 TInt LocalWrite(TInt aArgIndex);
127 TInt TestDesLength(TInt aArgIndex);
129 TInt SpeedTest(TSpeedTest);
130 TInt Echo(TInt aWhat, TInt a0, TInt a1, TInt a2, TInt a3);
131 void StartAsync(TRequestStatus& aStatus);
132 void CompleteAsync(TInt aIndex);
136 TInt SendMessage(TInt aMessage, TInt aArgIndex, TDesC* aDesArg, TInt8 aOffset = 0);
137 TInt SendMessage(TInt aMessage, TInt aArgIndex, TDes* aDesArg, TInt8 aOffset = 0);
138 TInt SendMessageDup(TInt aMessage, TInt aArgIndex, TInt aArgIndex2, TDes* aDesArgs);
141 LOCAL_D RTest test(_L("T_SVR"));
142 LOCAL_D RTest testSvr(_L("T_SVR Server"));
143 LOCAL_D RTest testSpeedy(_L("T_SVR Speedy"));
144 LOCAL_D TRequestStatus speedTestStatus;
145 LOCAL_D RThread serverThread;
146 LOCAL_D RProcess serverProcess;
151 CMySession::CMySession()
157 CMySession::~CMySession()
159 // Call User::Exit so server shuts down when client disconnects
160 User::Exit(KErrNone);
163 void CMySession::DisplayName(const RMessage2& aM)
165 // Display the client's name.
170 TInt r = aM.Client(t);
171 testSvr(r==KErrNone);
172 TFullName fn(t.FullName());
176 testSvr(r==KErrNone);
177 testSvr.Printf(_L("Session %S\n%S\n"), &fn, &text);
180 CMyServer* CMyServer::New(TInt aPriority)
182 // Create a new CMyServer.
186 return new CMyServer(aPriority);
189 CMyServer::CMyServer(TInt aPriority)
193 : CServer2(aPriority)
196 CSession2* CMyServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const
198 // Create a new client for this server.
202 TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
203 if (!User::QueryVersionSupported(v,aVersion))
204 User::Leave(KErrNotSupported);
205 return(new(ELeave) CMySession());
208 void CMySession::ServiceL(const RMessage2& aMessage)
210 // Handle messages for this server.
214 TInt f = aMessage.Function();
217 TInt what = f & 0x3fffffff;
218 TInt a0 = aMessage.Int0();
219 TInt a1 = aMessage.Int1();
220 TInt a2 = aMessage.Int2();
221 TInt a3 = aMessage.Int3();
225 aMessage.Complete(a0);
228 aMessage.Complete(a1);
231 aMessage.Complete(a2);
234 aMessage.Complete(a3);
237 aMessage.Complete(a0+a1+a2+a3);
240 aMessage.Complete(a0*a0+a1*a1+a2*a2+a3*a3);
251 TInt message = f & 0xff;
252 TInt arg = (f >> 8) & 0xff;
253 TInt8 offset = (TInt8)((f >> 16) & 0xff);
257 case CMyServer::EDisplay:
258 DisplayName(aMessage);
260 case CMyServer::ERead:
261 r=aMessage.Read(arg,b,offset);
262 if (r==KErrNone && b!=KReadDesContents)
265 case CMyServer::EGetDesLength:
266 r=aMessage.GetDesLength(arg);
268 case CMyServer::EGetDesMaxLength:
269 r=aMessage.GetDesMaxLength(arg);
271 case CMyServer::EWrite:
272 r=aMessage.Write(arg,KWriteDesContents,offset);
273 // Test descriptor length updated
274 if (r == KErrNone && aMessage.GetDesLength(arg) != 10)
276 // Test reading descriptor back again
278 r = aMessage.Read(arg,b,offset);
279 if (r==KErrNone && b!=KWriteDesContents)
282 case CMyServer::ELocalWrite:
286 des = (TDes*)aMessage.Int0();
289 des = (TDes*)aMessage.Int1();
292 des = (TDes*)aMessage.Int2();
295 des = (TDes*)aMessage.Int3();
302 *des = KLocalWriteDesContents;
303 r = aMessage.GetDesLength(arg) == 11 ? KErrNone : KErrGeneral;
306 r=aMessage.Read(arg,b,0);
307 if (r==KErrNone && b!=KLocalWriteDesContents)
310 case CMyServer::EDupDes:
311 r=aMessage.Write(arg,KWriteDesContents);
312 if (r == KErrNone && aMessage.GetDesLength(offset/* used to pass 2nd arg here*/) != 10)
315 r = aMessage.Read(offset,b);
316 if (r==KErrNone && b!=KWriteDesContents)
319 case CMyServer::ENull:
321 case CMyServer::ESimpleRead:
322 r=aMessage.Read(arg,b);
324 case CMyServer::ESimpleWrite:
325 r=aMessage.Write(arg,KWriteDesContents);
327 case CMyServer::EStartAsync:
328 r=iAsyncRequests.Append(aMessage);
330 return; // don't complete message
332 case CMyServer::ECompleteAsync:
334 TInt index = aMessage.Int0();
335 if (iAsyncRequests.Count() <= index)
339 RMessagePtr2 asyncMessage = iAsyncRequests[index];
340 iAsyncRequests.Remove(index);
341 asyncMessage.Complete(KErrNone);
346 case CMyServer::EStop:
347 CActiveScheduler::Stop();
352 aMessage.Complete(r);
355 void CMyActiveScheduler::Error(TInt anError) const
357 // Called if any Run() method leaves.
361 testSvr.Panic(anError,_L("CMyActiveScheduler::Error"));
364 TInt RDisplay::Open(TInt aMessageSlots)
370 return(CreateSession(KServerName,Version(),aMessageSlots));
373 TInt RDisplay::Display(const TDesC& aMessage)
375 // Display a message.
379 TBuf<0x10> b(aMessage);
380 return(SendReceive(CMyServer::EDisplay,TIpcArgs(&b)));
383 TInt RDisplay::SendMessage(TInt aMessage, TInt aArgIndex, TDesC* aDesArg, TInt8 aOffset)
385 TInt f = aMessage | (aArgIndex << 8) | ((aOffset << 16) & 0x00ff0000);
387 args.Set(aArgIndex, aDesArg);
388 return SendReceive(f, args);
391 TInt RDisplay::SendMessage(TInt aMessage, TInt aArgIndex, TDes* aDesArg, TInt8 aOffset)
393 TInt f = aMessage | (aArgIndex << 8) | ((aOffset << 16) & 0x00ff0000);
395 args.Set(aArgIndex, aDesArg);
396 return SendReceive(f, args);
399 TInt RDisplay::SendMessageDup(TInt aMessage, TInt aArgIndex1, TInt aArgIndex2, TDes* aDesArg)
401 TInt f = aMessage | (aArgIndex1 << 8) | (aArgIndex2 << 16);
403 args.Set(aArgIndex1, aDesArg);
404 args.Set(aArgIndex2, aDesArg);
405 return SendReceive(f, args);
408 TInt RDisplay::Read(TInt aArgIndex)
410 // Test RMessage2::Read
413 HBufC* buf = HBufC::New(0x10);
415 *buf = KReadDesContents;
417 TBufC<0x10> des1(KReadDesContents);
418 TBuf<0x10> des2(KReadDesContents);
420 TPtr des4((TUint16*)des2.Ptr(), des2.Length(), des2.MaxLength());
423 // test successful read
424 test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, &des1));
425 test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, &des2));
426 test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, &des3));
427 test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, &des4));
428 test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, &des5));
430 // test negative offset
431 test_Equal(KErrArgument, SendMessage(CMyServer::ERead, aArgIndex, &des1, -1));
433 // test bad descriptors
436 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, (TDesC*)0x30000000));
439 const TInt KChunkSize = 4096;
440 test_KErrNone(chunk.CreateLocal(KChunkSize, KChunkSize));
441 test_Equal(KChunkSize, chunk.Size());
443 TDesC* ptr = (TDesC*)(chunk.Base() + KChunkSize - 8);
444 Mem::Copy(ptr, &des3, 8);
445 test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, ptr));
447 ptr = (TDesC*)(chunk.Base() + KChunkSize - 4);
448 Mem::Copy(ptr, &des3, 4);
449 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, ptr));
451 ptr = (TDesC*)(chunk.Base() + KChunkSize - 12);
452 Mem::Copy(ptr, &des4, 12);
453 test_Equal(KErrNone, SendMessage(CMyServer::ERead, aArgIndex, ptr));
455 ptr = (TDesC*)(chunk.Base() + KChunkSize - 8);
456 Mem::Copy(ptr, &des4, 8);
457 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, ptr));
459 ptr = (TDesC*)(chunk.Base() + KChunkSize - 4);
460 Mem::Copy(ptr, &des4, 4);
461 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, ptr));
465 ((TUint32*)&des3)[1] = 0x00001000; // make descriptor point to invalid memory
466 ((TUint32*)&des4)[2] = 0x00001000; // make descriptor point to invalid memory
467 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, &des3));
468 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::ERead, aArgIndex, &des4));
475 TInt RDisplay::TestDesLength(TInt aArgIndex)
477 // Test RMessage2::GetDesLength and RMessage2::GetDesMaxLength
480 HBufC* buf = HBufC::New(0x10);
482 *buf = KLengthDesContents;
484 TBufC<0x10> des1(KLengthDesContents);
485 TBuf<0x10> des2(KLengthDesContents);
487 TPtr des4((TUint16*)des2.Ptr(), des2.Length(), des2.MaxLength());
491 test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, &des1));
492 test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, &des2));
493 test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, &des3));
494 test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, &des4));
495 test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, &des5));
497 // test GetDesMaxLength
498 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, &des1));
499 test_Equal(0x10, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, &des2));
500 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, &des3));
501 test_Equal(0x10, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, &des4));
502 test_Equal(0x10, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, &des5));
504 // test bad descriptors
507 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesLength, aArgIndex, (TDesC*)0x30000000));
510 const TInt KChunkSize = 4096;
511 test_KErrNone(chunk.CreateLocal(KChunkSize, KChunkSize));
512 test_Equal(KChunkSize, chunk.Size());
514 TDesC* ptr = (TDesC*)(chunk.Base() + KChunkSize - 8);
515 Mem::Copy(ptr, &des3, 8);
516 test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, ptr));
518 ptr = (TDesC*)(chunk.Base() + KChunkSize - 4);
519 Mem::Copy(ptr, &des3, 4);
520 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesLength, aArgIndex, ptr));
522 ptr = (TDesC*)(chunk.Base() + KChunkSize - 12);
523 Mem::Copy(ptr, &des4, 12);
524 test_Equal(9, SendMessage(CMyServer::EGetDesLength, aArgIndex, ptr));
525 test_Equal(0x10, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, ptr));
527 ptr = (TDesC*)(chunk.Base() + KChunkSize - 8);
528 Mem::Copy(ptr, &des4, 8);
529 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesLength, aArgIndex, ptr));
530 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, ptr));
532 ptr = (TDesC*)(chunk.Base() + KChunkSize - 4);
533 Mem::Copy(ptr, &des4, 4);
534 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesLength, aArgIndex, ptr));
535 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EGetDesMaxLength, aArgIndex, ptr));
544 TInt RDisplay::Write(TInt aArgIndex)
546 // Get session to test CSession2::WriteL.
549 HBufC* buf = HBufC::New(0x10);
555 TPtr des4((TUint16*)des2.Ptr(), des2.Length(), des2.MaxLength());
558 // test successful write
559 test_Equal(KErrNone, SendMessage(CMyServer::EWrite, aArgIndex, &des2));
560 test(des2 == KWriteDesContents);
561 test_Equal(KErrNone, SendMessage(CMyServer::EWrite, aArgIndex, &des4));
562 test(des4 == KWriteDesContents);
563 test_Equal(KErrNone, SendMessage(CMyServer::EWrite, aArgIndex, &des5));
564 test(des5 == KWriteDesContents);
565 test(*buf == KWriteDesContents);
567 // test buffer too short
569 test_Equal(KErrOverflow, SendMessage(CMyServer::EWrite, aArgIndex, &small));
571 // test write to constant descriptors
572 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EWrite, aArgIndex, &des1));
573 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EWrite, aArgIndex, &des3));
575 // test negative offset
576 test_Equal(KErrArgument, SendMessage(CMyServer::EWrite, aArgIndex, &des2, -1));
578 // test multiple instances of same descriptor
579 for (TInt i = 0 ; i < 4 ; ++i)
584 test_Equal(KErrNone, SendMessageDup(CMyServer::EDupDes, aArgIndex, i, &des2));
585 test(des2 == KWriteDesContents);
589 // test bad descriptors - do this last as it corrupts the descriptors.
592 ((TUint32*)&des3)[1] = 0x00001000; // make descriptor point to invalid memory
593 ((TUint32*)&des4)[2] = 0x00001000; // make descriptor point to invalid memory
594 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EWrite, aArgIndex, &des3));
595 test_Equal(KErrBadDescriptor, SendMessage(CMyServer::EWrite, aArgIndex, &des4));
602 TInt RDisplay::LocalWrite(TInt aArgIndex)
604 // test local write to descriptor
607 test_Equal(KErrNone, SendMessage(CMyServer::ELocalWrite, aArgIndex, &des2));
608 test(des2 == KLocalWriteDesContents);
612 void RDisplay::StartAsync(TRequestStatus& aStatus)
614 SendReceive(CMyServer::EStartAsync, TIpcArgs(), aStatus);
617 void RDisplay::CompleteAsync(TInt aIndex)
619 test_KErrNone(SendReceive(CMyServer::ECompleteAsync, TIpcArgs(aIndex)));
622 TInt RDisplay::SendBlind()
624 return Send(CMyServer::EStartAsync);
627 TInt RDisplay::SpeedTest(TSpeedTest aTest)
629 TBuf<0x10> des(KReadDesContents);
636 while (speedTestStatus == KRequestPending)
638 r = SendReceive(CMyServer::ENull, TIpcArgs());
641 r = (r == KErrNone) ? count : KErrGeneral;
644 case ESpeedUnusedDes:
645 while (speedTestStatus == KRequestPending)
647 r = SendReceive(CMyServer::ENull, TIpcArgs(&des));
650 r = (r == KErrNone) ? count : KErrGeneral;
653 case ESpeedGetDesLength:
654 while (speedTestStatus == KRequestPending)
656 r = SendReceive(CMyServer::EGetDesLength, TIpcArgs(&des));
659 r = (r == 12) ? count : KErrGeneral;
662 case ESpeedGetMaxDesLength:
663 while (speedTestStatus == KRequestPending)
665 r = SendReceive(CMyServer::EGetDesMaxLength, TIpcArgs(&des));
668 r = (r == 0x10) ? count : KErrGeneral;
672 while (speedTestStatus == KRequestPending)
674 r = SendReceive(CMyServer::ESimpleRead, TIpcArgs(&des));
677 r = (r == KErrNone) ? count : KErrGeneral;
681 while (speedTestStatus == KRequestPending)
683 r = SendReceive(CMyServer::ESimpleWrite, TIpcArgs(&des));
686 r = (r == KErrNone) ? count : KErrGeneral;
695 TInt RDisplay::Stop()
701 return SendReceive(CMyServer::EStop, TIpcArgs());
704 TVersion RDisplay::Version()
706 // Return the current version.
710 TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
714 TInt RDisplay::Echo(TInt aWhat, TInt a0, TInt a1, TInt a2, TInt a3)
716 return SendReceive(0x40000000|aWhat, TIpcArgs(a0,a1,a2,a3));
719 LOCAL_C TInt serverThreadEntryPoint(TAny*)
721 // The entry point for the producer thread.
724 RThread().SetPriority(EPriorityMore);
726 CMyActiveScheduler* pR=new CMyActiveScheduler;
728 CActiveScheduler::Install(pR);
730 CMyServer* pS=CMyServer::New(0);
733 TInt r=pS->Start(KServerName);
734 testSvr(r==KErrNone);
736 RThread::Rendezvous(KErrNone);
737 RProcess::Rendezvous(KErrNone);
739 CActiveScheduler::Start();
746 LOCAL_C TInt RunPanicThread(RThread& aThread)
750 TBool jit = User::JustInTime();
751 User::SetJustInTime(EFalse);
753 User::WaitForRequest(s);
754 User::SetJustInTime(jit);
758 LOCAL_C TInt RogueThread1(TAny*)
760 // try to kill the kernel
762 TPtrC* p=(TPtrC*)0x00001000; // make descriptor point to invalid memory
763 mutex.CreateGlobal(*p,EOwnerProcess); // this should panic the thread
767 class RMessageT : public RMessage2
770 RMessageT(TLinAddr anAddr) { iFunction=0; iHandle=(TInt)anAddr; }
773 LOCAL_C TInt RogueThread2(TAny*)
775 // try to kill the kernel
776 RMessageT m(0x30000000);
777 m.Complete(KErrNone); // this should panic the thread
781 LOCAL_C TInt RogueThread3(TAny*)
783 // try to kill the kernel
784 RMessageT m(0x80000000);
785 m.Complete(KErrNone); // this should panic the thread
789 LOCAL_C TInt RogueThread4(TAny*)
791 // try to kill the kernel
792 RMessageT m(0x800fff00); // this should be off the end of the kernel heap
793 m.Complete(KErrNone); // this should panic the thread
797 LOCAL_C void DisplayThreadExitInfo(const RThread& aThread)
799 TFullName fn=aThread.FullName();
800 TExitType exitType=aThread.ExitType();
801 TInt exitReason=aThread.ExitReason();
802 TBuf<32> exitCat=aThread.ExitCategory();
803 test.Printf(_L("Thread %S exited %d,%d,%S\n"),&fn,exitType,exitReason,&exitCat);
806 LOCAL_C void RogueThreadTest()
808 test.Start(_L("Rogue thread tests"));
814 test.Next(_L("Rogue thread test 1"));
815 r=thread.Create(_L("Rogue1"),RogueThread1,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
817 RunPanicThread(thread);
818 DisplayThreadExitInfo(thread);
819 test(thread.ExitType()==EExitPanic);
820 test(thread.ExitReason()==ECausedException);
821 CLOSE_AND_WAIT(thread);
824 test.Next(_L("Rogue thread test 2"));
825 r=thread.Create(_L("Rogue2"),RogueThread2,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
827 RunPanicThread(thread);
828 DisplayThreadExitInfo(thread);
829 test(thread.ExitType()==EExitPanic);
830 test(thread.ExitReason()==EBadMessageHandle);
831 CLOSE_AND_WAIT(thread);
833 test.Next(_L("Rogue thread test 3"));
834 r=thread.Create(_L("Rogue3"),RogueThread3,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
836 RunPanicThread(thread);
837 DisplayThreadExitInfo(thread);
838 test(thread.ExitType()==EExitPanic);
839 test(thread.ExitReason()==EBadMessageHandle);
840 CLOSE_AND_WAIT(thread);
842 test.Next(_L("Rogue thread test 4"));
843 r=thread.Create(_L("Rogue4"),RogueThread4,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
845 RunPanicThread(thread);
846 DisplayThreadExitInfo(thread);
847 test(thread.ExitType()==EExitPanic);
848 test(thread.ExitReason()==EBadMessageHandle);
849 CLOSE_AND_WAIT(thread);
853 class RMySession : public RSessionBase
856 TInt Connect(RServer2 aSrv,TRequestStatus& aStat)
857 {return CreateSession(aSrv,TVersion(),1,EIpcSession_Unsharable,0,&aStat);}
858 void SendTestMessage(TRequestStatus& aStat)
859 {SendReceive(0,TIpcArgs(1,2,3,4), aStat);}
862 TInt BadServerThread(TAny*)
868 RMessage2* badMsg = 0;
871 // Test receiving connect message to bad address
873 r = srv.CreateGlobal(KNullDesC);
876 r = sess.Connect(srv,stat);
879 srv.Receive(*badMsg);
881 User::WaitForRequest(stat);
882 if (stat != KErrServerTerminated)
886 // Test receiving normal message to bad address
888 r = srv.CreateGlobal(KNullDesC);
891 r = sess.Connect(srv,stat);
895 msg.Complete(KErrNone);
896 User::WaitForRequest(stat);
897 if (stat != KErrNone)
899 sess.SendTestMessage(stat);
900 srv.Receive(*badMsg);
902 User::WaitForRequest(stat);
903 if (stat != KErrServerTerminated)
912 // This tests the current behaviour of RServer2::Receive when passed a dodgy RMessage2 pointer,
913 // which is to ingore exceptions and not panic the server thread.
916 TInt r=thread.Create(_L("BadServer"),BadServerThread,KDefaultStackSize,NULL,NULL);
918 TRequestStatus status;
919 thread.Logon(status);
921 User::WaitForRequest(status);
922 test(thread.ExitType()==EExitKill);
923 test(thread.ExitReason()==23);
924 CLOSE_AND_WAIT(thread);
927 void StartServerThread()
929 TInt r=serverThread.Create(_L("Server"),serverThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
932 TRequestStatus status;
933 serverThread.Rendezvous(status);
934 serverThread.Resume();
936 User::WaitForRequest(status);
937 test(status == KErrNone);
940 void WaitServerThreadDeath()
942 TRequestStatus status;
943 serverThread.Logon(status);
944 User::WaitForRequest(status);
945 test(status == KErrNone);
946 test(serverThread.ExitReason() == EExitKill);
947 CLOSE_AND_WAIT(serverThread);
950 void StartServerProcess()
952 TInt r=serverProcess.Create(_L("t_svr"),_L("slave"));
955 TRequestStatus status;
956 serverProcess.Rendezvous(status);
957 serverProcess.Resume();
959 User::WaitForRequest(status);
960 test(status == KErrNone);
963 void WaitServerProcessDeath()
965 TRequestStatus status;
966 serverProcess.Logon(status);
967 User::WaitForRequest(status);
968 test(status == KErrNone);
969 test(serverProcess.ExitReason() == EExitKill);
970 CLOSE_AND_WAIT(serverProcess);
973 void RunSpeedTest(RDisplay& aSess, TBool aLocal, TSpeedTest aTest)
978 test(timer.CreateLocal() == KErrNone);
980 timer.After(speedTestStatus, 300000);
981 TInt r = aSess.SpeedTest(aTest);
982 User::WaitForRequest(speedTestStatus);
985 timer.After(speedTestStatus, 3000000);
986 TUint startCount = User::FastCounter();
987 r = aSess.SpeedTest(aTest);
988 TUint endCount = User::FastCounter();
989 User::WaitForRequest(speedTestStatus);
994 const TDesC* loc = aLocal ? &KLitLocal : &KLitRemote;
995 const TDesC* name = KSpeedTestNames[aTest];
998 test(HAL::Get(HAL::EFastCounterFrequency, countFreq) == KErrNone);
1000 TBool fcCountsUp = 0;
1001 test(HAL::Get(HAL::EFastCounterCountsUp, fcCountsUp) == KErrNone);
1003 TInt countDiff = fcCountsUp ? (endCount - startCount) : (startCount - endCount);
1004 TReal elapsedTimeUs = (1000000.0 * countDiff) / countFreq;
1005 TReal time = elapsedTimeUs / r;
1007 test.Printf(_L("%S, %S, %f\n"), loc, name, time);
1010 void RunAllSpeedTests(TBool aLocal)
1013 test(t.Open() == KErrNone);
1015 RunSpeedTest(t, aLocal, ESpeedNull);
1016 RunSpeedTest(t, aLocal, ESpeedUnusedDes);
1017 RunSpeedTest(t, aLocal, ESpeedGetDesLength);
1018 RunSpeedTest(t, aLocal, ESpeedGetMaxDesLength);
1019 RunSpeedTest(t, aLocal, ESpeedReadDes);
1020 RunSpeedTest(t, aLocal, ESpeedWriteDes);
1025 const TInt KMaxRequests = 20;
1026 const TInt KSoakIterations = 1000;
1028 void DoTestMultipleOutstandingRequests(RDisplay t)
1030 TRequestStatus status[KMaxRequests];
1032 test.Start(_L("Test multiple async requests\n"));
1034 test.Next(_L("Test multiple async requests, complete in order\n"));
1036 for (i = 0 ; i < KMaxRequests ; ++i)
1038 t.StartAsync(status[i]);
1039 test_Equal(KRequestPending, status[i].Int());
1041 for (i = 0 ; i < KMaxRequests ; ++i)
1043 t.CompleteAsync(0); // complete first remaining async request
1044 User::WaitForAnyRequest();
1045 test_KErrNone(status[i].Int());
1048 test.Next(_L("Test multiple async requests, complete in reverse order\n"));
1049 for (i = 0 ; i < KMaxRequests ; ++i)
1051 t.StartAsync(status[i]);
1052 test_Equal(KRequestPending, status[i].Int());
1054 for (i = KMaxRequests - 1 ; i >= 0 ; --i)
1056 t.CompleteAsync(i); // complete last remaining async request
1057 User::WaitForAnyRequest();
1058 test_KErrNone(status[i].Int());
1061 test.Next(_L("Soak test multiple async requests, complete in random order\n"));
1062 for (i = 0 ; i < KMaxRequests ; ++i)
1064 t.StartAsync(status[i]);
1065 test_Equal(KRequestPending, status[i].Int());
1067 for (TInt j = 0 ; j < KSoakIterations ; ++j)
1069 // complete random async request
1070 i = Math::Random() % KMaxRequests;
1072 User::WaitForAnyRequest();
1074 // find which one got completed
1075 for (i = 0 ; i < KMaxRequests ; ++i)
1076 if (status[i] != KRequestPending)
1078 test(i < KMaxRequests);
1079 test_KErrNone(status[i].Int());
1082 t.StartAsync(status[i]);
1083 test_Equal(KRequestPending, status[i].Int());
1086 test.Printf(_L("."));
1088 test.Printf(_L("\n"));
1089 for (i = 0 ; i < KMaxRequests ; ++i)
1092 User::WaitForAnyRequest();
1094 for (i = 0 ; i < KMaxRequests ; ++i)
1095 test_KErrNone(status[i].Int());
1100 void TestMultipleOutstandingRequests()
1102 TRequestStatus status[2];
1104 test.Next(_L("Test zero async message slots\n"));
1106 StartServerThread();
1107 test_KErrNone(t.Open(0));
1108 t.StartAsync(status[0]);
1109 User::WaitForAnyRequest();
1110 test_Equal(KErrServerBusy, status[0].Int());
1112 WaitServerThreadDeath();
1114 test.Next(_L("Test one async request\n"));
1115 StartServerThread();
1116 test_KErrNone(t.Open(1));
1117 t.StartAsync(status[0]);
1118 t.StartAsync(status[1]);
1119 User::WaitForAnyRequest();
1120 test_Equal(KRequestPending, status[0].Int());
1121 test_Equal(KErrServerBusy, status[1].Int());
1123 test_Equal(KRequestPending, status[0].Int());
1125 User::WaitForAnyRequest();
1126 test_KErrNone(status[0].Int());
1128 test.Next(_L("Test one async request, again\n"));
1129 t.StartAsync(status[0]);
1130 test_Equal(KRequestPending, status[0].Int());
1132 User::WaitForAnyRequest();
1133 test_KErrNone(status[0].Int());
1135 WaitServerThreadDeath();
1137 test.Next(_L("Test multiple async requests using dedicated message slots\n"));
1138 StartServerThread();
1139 test_KErrNone(t.Open(KMaxRequests));
1140 DoTestMultipleOutstandingRequests(t);
1142 WaitServerThreadDeath();
1144 test.Next(_L("Test multiple async requests using global pool\n"));
1145 StartServerThread();
1146 test_KErrNone(t.Open(-1));
1147 DoTestMultipleOutstandingRequests(t);
1149 WaitServerThreadDeath();
1152 void CheckNoOutstandingSignals()
1155 test_KErrNone(timer.CreateLocal());
1156 TRequestStatus status;
1157 timer.After(status, 1000);
1158 User::WaitForAnyRequest();
1159 test_KErrNone(status.Int());
1163 void TestBlindMessages()
1165 test.Start(_L("Test sending blind messages to server"));
1166 CheckNoOutstandingSignals();
1169 StartServerThread();
1170 test_KErrNone(t.Open(0));
1171 test_Equal(KErrServerBusy, t.SendBlind());
1173 WaitServerThreadDeath();
1175 StartServerThread();
1176 test_KErrNone(t.Open(2));
1177 test_KErrNone(t.SendBlind());
1178 test_KErrNone(t.SendBlind());
1179 test_Equal(KErrServerBusy, t.SendBlind());
1181 test_KErrNone(t.SendBlind());
1182 test_Equal(KErrServerBusy, t.SendBlind());
1185 test_KErrNone(t.SendBlind());
1186 test_KErrNone(t.SendBlind());
1187 test_Equal(KErrServerBusy, t.SendBlind());
1191 WaitServerThreadDeath();
1193 CheckNoOutstandingSignals();
1197 void RunCommonServerTests(TBool /*aSameProcess*/)
1199 test.Start(_L("Connect to server"));
1204 test.Next(_L("Test all args passed"));
1205 test(t.Echo(0,3,5,7,11)==3);
1206 test(t.Echo(1,3,5,7,11)==5);
1207 test(t.Echo(2,3,5,7,11)==7);
1208 test(t.Echo(3,3,5,7,11)==11);
1209 test(t.Echo(4,3,5,7,11)==26);
1210 test(t.Echo(5,3,5,7,11)==204);
1212 test.Next(_L("Send to server"));
1213 r=t.Display(_L("First message"));
1216 for (TInt i = 0 ; i < 4 ; ++i)
1218 test.Start(_L("Testing passing descriptors"));
1219 test.Printf(_L("Descriptor passed as arg %d\n"), i);
1221 test.Next(_L("Read"));
1225 test.Next(_L("GetDesLength, GetDesMaxLength"));
1226 r=t.TestDesLength(i);
1229 test.Next(_L("Write"));
1234 This is now explicitly not supported!
1237 test.Next(_L("Local write"));
1246 test.Next(_L("Test RServer2::Receive to dodgy pointer"));
1261 // Turn off evil lazy dll unloading
1263 test(l.Connect()==KErrNone);
1264 test(l.CancelLazyDllUnload()==KErrNone);
1267 test.Start(_L("Running tests for server in remote process"));
1269 StartServerProcess();
1270 RunCommonServerTests(EFalse);
1271 WaitServerProcessDeath();
1273 test.Next(_L("Running tests for server in same process"));
1274 StartServerThread();
1275 RunCommonServerTests(ETrue);
1276 WaitServerThreadDeath();
1278 test.Next(_L("Running rogue thread test"));
1281 test.Next(_L("Test multiple outstanding requests"));
1282 TestMultipleOutstandingRequests();
1284 test.Next(_L("Test sending blind async requests"));
1285 TestBlindMessages();
1288 test.Next(_L("Running speed tests"));
1289 test.Printf(_L("Server process, Test name, Time (uS)\n"));
1291 StartServerProcess();
1292 RunAllSpeedTests(EFalse);
1293 WaitServerProcessDeath();
1295 StartServerThread();
1296 RunAllSpeedTests(ETrue);
1297 WaitServerThreadDeath();
1304 GLDEF_C TInt E32Main()
1306 if (User::CommandLineLength() == 0)
1312 return serverThreadEntryPoint(NULL);