Update contrib.
1 // Copyright (c) 2005-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\system\t_svr_connect.cpp
16 // Tests correct operation of server when interleaving connect/disconnect/
17 // other messages and creating the user-side session object (setting the
18 // session cookie) in interesting manners.
19 // Tests that clients/servers are panicked when performing illegal operations
20 // w.r.t. server connection, i.e. a client thread may not send more than one
21 // connect message simultaneously, nor may it send another connect message
22 // once a connect message has been successfully completed. Similarly, a server
23 // may not set the cookie twice nor may it set the cookie to be NULL. Also, a
24 // server may only set the cookie from a connect message and from no other.
28 // - Test asynchronous server connect in various ways. Verify results
30 // - Test illegal client/server behaviour. Verify threads are panicked,
32 // Platforms/Drives/Compatibility:
34 // Assumptions/Requirement/Pre-requisites:
36 // Failures and causes:
37 // Failure of this test would be caused by an incorrect modification of
38 // the internal client/server mechanism in the kernel.
39 // Base Port information:
40 // This is a unit test of the client/server mechanism within the kernel.
41 // It should be invariant to base ports. If the kernel proper has not been
42 // modified, this test should not fail with any new base port.
47 #include "../misc/int_svr_calls.h"
50 _LIT(KTestName, "t_svr_connect");
51 LOCAL_D RTest test(KTestName);
52 LOCAL_D RTest test_client(KTestName);
53 LOCAL_D RTest test_server(KTestName);
55 _LIT(KServerName, "t_svr_connect");
56 _LIT8(KServerName8, "t_svr_connect");
57 _LIT(KMainThread, "main thread");
58 _LIT(KServerThread, "server thread");
59 _LIT(KClientThread, "client thread");
60 _LIT(KClientThread2, "client thread2");
61 _LIT(KClientThread3, "client thread3");
63 class RTestServer : public RSessionBase
66 inline static TInt CreateSession(TInt aMsgSlots) { return SessionCreate(KServerName8,aMsgSlots,NULL,EIpcSession_Sharable); }
75 // Things to do in the server:
80 // receive a.n.other 7
81 // complete a.n.other 8
82 // receive disconnect 9
83 // complete disconnect 10
115 static TMsgType TheMsgType;
116 static TServerControl TheServerControl;
117 static TClientControl TheClientControl;
118 static RSemaphore ServerSemaphore;
119 static RSemaphore ClientSemaphore;
120 static RSemaphore TaskCompletionSemaphore;
121 static RMessage2 Msgs[EMsgCount];
122 static RServer2 Server;
123 static RThread ServerThread;
124 static RThread ClientThread;
125 static RTestServer ServerHandle;
126 static TRequestStatus ConnectStatus;
127 static TRequestStatus ANOtherStatus;
128 static TRequestStatus ANOther2Status;
129 static TRequestStatus ServerReceiveStatus;
130 static TInt TheNumberOfMsgSlots;
131 static TInt ErrorExpected;
132 static User::TCritical CriticalLevel;
135 static const TAny* const KSessionCookie = (const TAny*)0x12345;
136 static TRequestStatus* volatile KNullReference = 0;
138 void DoServerAction();
139 void DoClientAction();
142 TInt TestThreadServer(TAny*)
144 test_server(Server.CreateGlobal(KServerName) == KErrNone);
145 RThread::Rendezvous(KErrNone);
149 ServerSemaphore.Wait();
151 TaskCompletionSemaphore.Signal();
172 TRequestStatus& RequestStatus()
177 return ConnectStatus;
179 return ANOtherStatus;
181 return ANOther2Status;
185 return *(TRequestStatus*)KNullReference;
188 void DoServerAction()
190 switch (TheServerControl)
194 RMessage2& msg = Msgs[Index()];
196 test_server(msg.Function() == TheMsgType);
199 case EReceiveBlocked:
201 RMessage2& msg = Msgs[Index()];
202 Server.Receive(msg, ServerReceiveStatus);
203 test_server(ServerReceiveStatus.Int() == KRequestPending);
206 case EWaitForReceive:
208 User::WaitForRequest(ServerReceiveStatus);
209 test_server(ServerReceiveStatus.Int() == KErrNone);
210 test_server(Msgs[Index()].Function() == TheMsgType);
215 SetSessionPtr(Msgs[Index()].Handle(), KSessionCookie);
220 SetSessionPtr(Msgs[Index()].Handle(), NULL);
225 Msgs[Index()].Complete(KErrNone);
242 ServerThread.Create(KServerThread, TestThreadServer, KDefaultStackSize, 4096, 4096, NULL);
244 TRequestStatus started;
245 ServerThread.Rendezvous(started);
247 ServerThread.Resume();
248 User::WaitForRequest(started);
250 test(started.Int() == KErrNone);
255 TRequestStatus logon;
256 ServerThread.Logon(logon);
258 TheServerControl = EServerDie;
259 ServerSemaphore.Signal();
261 User::WaitForRequest(logon);
262 test(logon.Int() == KErrNone);
264 CLOSE_AND_WAIT(ServerThread);
267 TInt TestThreadClient(TAny*)
269 RThread::Rendezvous(KErrNone);
273 ClientSemaphore.Wait();
275 TaskCompletionSemaphore.Signal();
279 void DoClientAction()
281 switch (TheClientControl)
285 if (TheMsgType == EDisConnect)
286 ServerHandle.Close();
288 SessionSend(ServerHandle.Handle(), TheMsgType, NULL, &RequestStatus());
293 User::WaitForRequest(RequestStatus());
298 TInt err = ServerHandle.SetReturnedHandle(RTestServer::CreateSession(TheNumberOfMsgSlots));
300 if (err != ErrorExpected)
302 test_client.Printf(_L("Error returned = %d\n"),err);
303 test_client(EFalse,__LINE__);
309 User::SetCritical(User::ENotCritical);
315 User::SetCritical(CriticalLevel);
325 // I'm lazy and I haven't completed all the IPC the client thread does,
326 // so even when the client thread panics, the DObject is still kept alive
327 // until the server goes away. Therefore if I want another client I rename.
328 void StartClient(const TDesC& aName)
330 ClientThread.Create(aName, TestThreadClient, KDefaultStackSize, 4096, 4096, NULL);
332 TRequestStatus started;
333 ClientThread.Rendezvous(started);
335 ClientThread.Resume();
336 User::WaitForRequest(started);
338 test(started.Int() == KErrNone);
343 StartClient(KClientThread);
348 TRequestStatus logon;
349 ClientThread.Logon(logon);
351 TheClientControl = EClientDie;
352 ClientSemaphore.Signal();
354 User::WaitForRequest(logon);
355 test(logon.Int() == KErrNone);
357 CLOSE_AND_WAIT(ClientThread);
360 void CreateSemaphores()
362 TInt err = ServerSemaphore.CreateLocal(0);
363 test(err == KErrNone);
364 err = ClientSemaphore.CreateLocal(0);
365 test(err == KErrNone);
366 err = TaskCompletionSemaphore.CreateLocal(0);
367 test(err == KErrNone);
370 void CloseSemaphores()
372 ServerSemaphore.Close();
373 ClientSemaphore.Close();
374 TaskCompletionSemaphore.Close();
377 void CreateSession(TInt aErrorExpected=KErrNone, TInt aMsgSlots=-1)
379 TheClientControl = ECreateSession;
380 TheNumberOfMsgSlots = aMsgSlots;
381 ErrorExpected=aErrorExpected;
382 ClientSemaphore.Signal();
383 TaskCompletionSemaphore.Wait();
386 void SendMsg(TMsgType aType)
388 TheClientControl = ESendMsg;
390 ClientSemaphore.Signal();
391 TaskCompletionSemaphore.Wait();
394 void SendMsg_NoWait(TMsgType aType)
396 TheClientControl = ESendMsg;
398 ClientSemaphore.Signal();
401 void WaitMsg(TMsgType aType)
403 TheClientControl = EWaitMsg;
405 ClientSemaphore.Signal();
406 TaskCompletionSemaphore.Wait();
409 void ReceiveBlocked(TMsgType aType)
411 TheServerControl = EReceiveBlocked;
413 ServerSemaphore.Signal();
414 TaskCompletionSemaphore.Wait();
417 void WaitForReceive(TMsgType aType)
419 TheServerControl = EWaitForReceive;
421 ServerSemaphore.Signal();
422 TaskCompletionSemaphore.Wait();
425 void ReceiveMsg(TMsgType aType)
427 TheServerControl = EReceiveMsg;
429 ServerSemaphore.Signal();
430 TaskCompletionSemaphore.Wait();
433 void CompleteMsg(TMsgType aType)
435 TheServerControl = ECompleteMsg;
437 ServerSemaphore.Signal();
438 TaskCompletionSemaphore.Wait();
443 TheServerControl = ESetCookie;
444 TheMsgType = EConnect;
445 ServerSemaphore.Signal();
446 TaskCompletionSemaphore.Wait();
449 void SetCookie_NoWait()
451 TheServerControl = ESetCookie;
452 TheMsgType = EConnect;
453 ServerSemaphore.Signal();
458 TheServerControl = ESetNullCookie;
459 TheMsgType = EConnect;
460 ServerSemaphore.Signal();
463 void SetBadCookie(TMsgType aType)
465 TheServerControl = ESetCookie;
466 test(aType != EConnect);
468 ServerSemaphore.Signal();
470 void SetClientCritical(User::TCritical aCritical)
472 TheClientControl = ESetCritical;
473 CriticalLevel=aCritical;
474 ClientSemaphore.Signal();
475 TaskCompletionSemaphore.Wait();
480 test.Next(_L("Create session with test server"));
482 test.Next(_L("Send connect message"));
484 test.Next(_L("Send A.N.Other message"));
486 test.Next(_L("Sending disconnect message"));
487 SendMsg(EDisConnect);
488 test.Next(_L("Receive A.N.Other message"));
489 ReceiveMsg(EANOther);
490 test(Msgs[Index()].Session() == NULL);
491 test.Next(_L("Receive disconnect message"));
492 ReceiveMsg(EDisConnect);
493 test.Next(_L("Check the session has gone"));
494 test(Msgs[Index()].Session() == NULL);
495 test.Next(_L("Set up receive for next test"));
496 ReceiveBlocked(EConnect);
501 test.Next(_L("Create session with test server"));
503 test.Next(_L("Send connect message"));
505 test.Next(_L("Send A.N.Other message"));
507 test.Next(_L("Receive connect message"));
508 WaitForReceive(EConnect);
509 test(Msgs[Index()].Session() == NULL);
510 test.Next(_L("Receive A.N.Other message"));
511 ReceiveMsg(EANOther);
512 test(Msgs[Index()].Session() == NULL);
513 test.Next(_L("Sending disconnect message"));
514 SendMsg(EDisConnect);
515 test.Next(_L("Await disconnect message"));
516 ReceiveBlocked(EDisConnect);
517 test.Next(_L("Set cookie"));
519 test.Next(_L("Check disconnect message received"));
520 WaitForReceive(EDisConnect);
521 test(Msgs[Index()].Session() == KSessionCookie);
522 test.Next(_L("Complete connect message"));
523 CompleteMsg(EConnect);
531 ReceiveMsg(EConnect);
532 test(Msgs[Index()].Session() == NULL);
533 ReceiveMsg(EANOther);
534 test(Msgs[Index()].Session() == NULL);
535 SendMsg(EDisConnect);
536 ReceiveBlocked(EDisConnect);
537 CompleteMsg(EConnect);
538 WaitForReceive(EDisConnect);
539 test(Msgs[Index()].Session() == NULL);
547 ReceiveMsg(EConnect);
548 test(Msgs[Index()].Session() == NULL);
550 ReceiveMsg(EANOther);
551 test(Msgs[Index()].Session() == KSessionCookie);
552 SendMsg(EDisConnect);
553 ReceiveMsg(EDisConnect);
554 test(Msgs[Index()].Session() == KSessionCookie);
561 ReceiveMsg(EConnect);
562 test(Msgs[Index()].Session() == NULL);
564 ReceiveMsg(EANOther);
565 test(Msgs[Index()].Session() == NULL);
566 SendMsg(EDisConnect);
567 ReceiveBlocked(EDisConnect);
569 WaitForReceive(EDisConnect);
570 test(Msgs[Index()].Session() == KSessionCookie);
571 CompleteMsg(EConnect);
578 ReceiveMsg(EConnect);
579 test(Msgs[Index()].Session() == NULL);
581 ReceiveMsg(EANOther);
582 test(Msgs[Index()].Session() == NULL);
583 SendMsg(EDisConnect);
584 ReceiveBlocked(EDisConnect);
585 CompleteMsg(EConnect);
586 WaitForReceive(EDisConnect);
587 test(Msgs[Index()].Session() == NULL);
594 ReceiveMsg(EConnect);
595 test(Msgs[Index()].Session() == NULL);
598 ReceiveMsg(EANOther);
599 test(Msgs[Index()].Session() == KSessionCookie);
600 SendMsg(EDisConnect);
601 ReceiveMsg(EDisConnect);
602 test(Msgs[Index()].Session() == KSessionCookie);
611 SendMsg(EDisConnect);
612 ReceiveMsg(EANOther);
613 test(Msgs[Index()].Session() == NULL);
614 ReceiveMsg(EANOther2);
615 test(Msgs[Index()].Session() == NULL);
616 ReceiveMsg(EDisConnect);
617 test(Msgs[Index()].Session() == NULL);
626 ReceiveMsg(EANOther);
627 test(Msgs[Index()].Session() == NULL);
628 SendMsg(EDisConnect);
629 ReceiveMsg(EANOther2);
630 test(Msgs[Index()].Session() == NULL);
631 ReceiveMsg(EDisConnect);
632 test(Msgs[Index()].Session() == NULL);
633 ReceiveBlocked(EANOther);
642 WaitForReceive(EANOther);
643 test(Msgs[Index()].Session() == NULL);
644 ReceiveMsg(EConnect);
645 test(Msgs[Index()].Session() == NULL);
646 ReceiveMsg(EANOther2);
647 test(Msgs[Index()].Session() == NULL);
648 SendMsg(EDisConnect);
649 ReceiveBlocked(EDisConnect);
651 WaitForReceive(EDisConnect);
652 test(Msgs[Index()].Session() == KSessionCookie);
653 CompleteMsg(EConnect);
662 ReceiveMsg(EANOther);
663 test(Msgs[Index()].Session() == NULL);
664 ReceiveMsg(EConnect);
665 test(Msgs[Index()].Session() == NULL);
666 ReceiveMsg(EANOther2);
667 test(Msgs[Index()].Session() == NULL);
668 SendMsg(EDisConnect);
669 ReceiveBlocked(EDisConnect);
670 CompleteMsg(EConnect);
671 WaitForReceive(EDisConnect);
672 test(Msgs[Index()].Session() == NULL);
681 ReceiveMsg(EANOther);
682 test(Msgs[Index()].Session() == NULL);
683 ReceiveMsg(EConnect);
684 test(Msgs[Index()].Session() == NULL);
686 ReceiveMsg(EANOther2);
687 test(Msgs[Index()].Session() == KSessionCookie);
688 SendMsg(EDisConnect);
689 ReceiveMsg(EDisConnect);
690 test(Msgs[Index()].Session() == KSessionCookie);
698 ReceiveMsg(EANOther);
699 test(Msgs[Index()].Session() == NULL);
701 ReceiveMsg(EConnect);
702 test(Msgs[Index()].Session() == NULL);
704 ReceiveMsg(EANOther2);
705 test(Msgs[Index()].Session() == KSessionCookie);
706 SendMsg(EDisConnect);
707 ReceiveMsg(EDisConnect);
708 test(Msgs[Index()].Session() == KSessionCookie);
716 ReceiveMsg(EANOther);
717 test(Msgs[Index()].Session() == NULL);
718 ReceiveMsg(EConnect);
719 test(Msgs[Index()].Session() == NULL);
722 ReceiveMsg(EANOther2);
723 test(Msgs[Index()].Session() == KSessionCookie);
724 SendMsg(EDisConnect);
725 ReceiveMsg(EDisConnect);
726 test(Msgs[Index()].Session() == KSessionCookie);
733 ReceiveMsg(EANOther);
734 test(Msgs[Index()].Session() == NULL);
736 ReceiveMsg(EConnect);
737 test(Msgs[Index()].Session() == NULL);
740 ReceiveMsg(EANOther2);
741 test(Msgs[Index()].Session() == KSessionCookie);
742 SendMsg(EDisConnect);
743 ReceiveMsg(EDisConnect);
744 test(Msgs[Index()].Session() == KSessionCookie);
749 // Try connecting with too many message slots
750 // (Check for DEF091903 regression)
751 CreateSession(KErrArgument, 1000);
754 _LIT(KKernExec, "KERN-EXEC");
756 void CheckClientDeath(TInt aReason)
758 TRequestStatus logon;
760 ClientThread.Logon(logon);
761 User::WaitForRequest(logon);
763 test(ClientThread.ExitType() == EExitPanic);
764 test(ClientThread.ExitCategory() == KKernExec);
765 test(ClientThread.ExitReason() == aReason);
767 ClientThread.Close();
768 ClientThread.SetHandle(KNullHandle);
771 void CheckServerDeath(TInt aReason)
773 TRequestStatus logon;
775 ServerThread.Logon(logon);
776 User::WaitForRequest(logon);
778 test(ServerThread.ExitType() == EExitPanic);
779 test(ServerThread.ExitCategory() == KKernExec);
780 test(ServerThread.ExitReason() == aReason);
782 CLOSE_AND_WAIT(ServerThread);
783 ServerThread.SetHandle(KNullHandle);
788 TBool jit = User::JustInTime();
789 User::SetJustInTime(EFalse);
791 SetClientCritical(User::ENotCritical);
792 test.Next(_L("Two connect msgs at once is naughty"));
795 ReceiveMsg(EConnect);
797 SendMsg_NoWait(EConnect);
798 CheckClientDeath(ERequestAlreadyPending);
799 StartClient(KClientThread2);
800 test.Next(_L("Another connect message after a sucessful connect msg is naughty"));
803 ReceiveMsg(EConnect);
805 CompleteMsg(EConnect);
806 SendMsg_NoWait(EConnect);
807 CheckClientDeath(ESessionAlreadyConnected);
808 StartClient(KClientThread3);
810 test.Next(_L("A null session cookie is naughty"));
813 ReceiveMsg(EConnect);
815 CheckServerDeath(ESessionNullCookie);
818 test.Next(_L("Setting the session cookie twice is naughty"));
821 ReceiveMsg(EConnect);
824 CheckServerDeath(ESessionCookieAlreadySet);
827 test.Next(_L("Trying to set the session cookie from a non-connect message is naughty"));
830 ReceiveMsg(EConnect);
832 ReceiveMsg(EANOther);
833 SetBadCookie(EANOther);
834 CheckServerDeath(ESessionInvalidCookieMsg);
837 User::SetJustInTime(jit);
842 User::RenameThread(KMainThread);
848 test.Start(_L("Creating semaphores"));
851 test.Next(_L("Starting test server"));
854 test.Next(_L("Starting test client"));
856 SetClientCritical(User::EProcessCritical);
857 // test combinations of receiving messages with messages sent by the client in the
858 // correct order (w.r.t to each other, but not necessarily to when messages are received)
859 test.Next(_L("Sending in order"));
875 // test combinations of receiving messages with messages sent by the client in the
876 // wrong order (w.r.t to each other, but not necessarily to when messages are received)
877 test.Next(_L("Sending out of order"));
897 test.Next(_L("Test other naughty behaviour is trapped"));
900 test.Next(_L("Stopping test client"));
903 test.Next(_L("Stopping test server"));
906 test.Next(_L("Closing semaphores"));