featuremgmt/featuremgr/test/rtest/src/t_fmgrbadclient.cpp
branchRCL_3
changeset 10 fa9941cf3867
child 11 667e88a979d7
equal deleted inserted replaced
6:5ffdb8f2067f 10:fa9941cf3867
       
     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 "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 //
       
    15 
       
    16 #include <e32test.h>
       
    17 #include <e32math.h>
       
    18 #include <featmgr.h>
       
    19 #include <featureuids.h>
       
    20 #include "featurepanics.h"
       
    21 #include <featurecontrol.h>
       
    22 #include <featurenotifier.h>
       
    23 #include "..\src\inc\featmgrconfiguration.h"
       
    24 #include "..\src\inc\featmgrclientserver.h"
       
    25 
       
    26 using namespace NFeature;
       
    27 
       
    28 static RTest TheTest(_L("t_fmgrbadclient"));
       
    29 
       
    30 const TInt KTestIterCount = 5000;
       
    31 
       
    32 enum TArgType 
       
    33     {
       
    34     EIntArgType, 
       
    35     ETextArgType, 
       
    36     EBinArgType, 
       
    37     ELastArgType
       
    38     };
       
    39 
       
    40 const TInt KMaxDesArgLen = 1000;
       
    41 
       
    42 //If the FeatMgr server crashes and the test receives KErrServerTerminated error, then the 
       
    43 //next set will contain the last:
       
    44 // - iteration number;
       
    45 // - handle type;
       
    46 // - function code;
       
    47 // - handle;
       
    48 // - IPC arguments values;
       
    49 struct TThreadData
       
    50     {
       
    51     TInt                iIteration;
       
    52     TInt                iFunction;
       
    53     TArgType            iArgType[KMaxMessageArguments];
       
    54     TInt                iIntArg[KMaxMessageArguments];
       
    55     TBuf<KMaxDesArgLen> iTextArg[KMaxMessageArguments];
       
    56     TBuf8<KMaxDesArgLen> iBinArg[KMaxMessageArguments];
       
    57     TInt64              iSeed;
       
    58     };
       
    59 
       
    60 _LIT(KPanicCategory, "SrvTerm");
       
    61 _LIT(KPanicCategory2, "InvArg");
       
    62 const TInt KPanicCode = 1111;
       
    63 const TInt KPanicCode2 = 2222;
       
    64 
       
    65 ///////////////////////////////////////////////////////////////////////////////////////
       
    66 
       
    67 //Deletes all created test files.
       
    68 void DestroyTestEnv()
       
    69     {
       
    70     }
       
    71 
       
    72 ///////////////////////////////////////////////////////////////////////////////////////
       
    73 ///////////////////////////////////////////////////////////////////////////////////////
       
    74 //Test macros and functions
       
    75 void Check1(TInt aValue, TInt aLine, TBool aPrintThreadName = EFalse)
       
    76     {
       
    77     if(!aValue)
       
    78         {
       
    79         DestroyTestEnv();
       
    80         if(aPrintThreadName)
       
    81             {
       
    82             RThread th;
       
    83             TName name = th.Name();
       
    84             RDebug::Print(_L("*** Expression evaluated to false. Thread %S, Line %d\r\n"), &name, aLine);
       
    85             }
       
    86         else
       
    87             {
       
    88             RDebug::Print(_L("*** Expression evaluated to false. Line %d\r\n"), aLine);
       
    89             }
       
    90         TheTest(EFalse, aLine);
       
    91         }
       
    92     }
       
    93 void Check2(TInt aValue, TInt aExpected, TInt aLine, TBool aPrintThreadName = EFalse)
       
    94     {
       
    95     if(aValue != aExpected)
       
    96         {
       
    97         DestroyTestEnv();
       
    98         if(aPrintThreadName)
       
    99             {
       
   100             RThread th;
       
   101             TName name = th.Name();
       
   102             RDebug::Print(_L("*** Thread %S, Line %d Expected error: %d, got: %d\r\n"), &name, aLine, aExpected, aValue);
       
   103             }
       
   104         else
       
   105             {
       
   106             RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue);
       
   107             }
       
   108         TheTest(EFalse, aLine);
       
   109         }
       
   110     }
       
   111 #define TEST(arg) ::Check1((arg), __LINE__)
       
   112 #define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__)
       
   113 #define TTEST(arg) ::Check1((arg), __LINE__, ETrue)
       
   114 #define TTEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__, ETrue)
       
   115 
       
   116 //////////////////////////////////////////////////////////////////////////////////////////////////
       
   117 
       
   118 static TInt StartFeatMgrServer()
       
   119     {
       
   120     RProcess server;
       
   121     const TUidType serverUid( KNullUid, KServerUid2, KNullUid );
       
   122     TInt err = server.Create( KServerExeName, // FeatMgrServer.exe
       
   123                            KNullDesC, // A descriptor containing data passed as 
       
   124                                       // an argument to the thread function of 
       
   125                                       // the new process's main thread, when it 
       
   126                                       // is first scheduled.
       
   127                            serverUid, // FeatMgr server UID
       
   128                            EOwnerProcess ); // Ownership of this process handle 
       
   129 
       
   130     // Return error code if we couldn't create a process
       
   131     if ( err == KErrNone )
       
   132         {
       
   133         // Rendezvous is used to detect server start
       
   134         TRequestStatus stat;
       
   135         server.Rendezvous( stat );
       
   136 
       
   137         if ( stat != KRequestPending )
       
   138             {
       
   139             server.Kill( KErrNone ); // Abort startup
       
   140             }
       
   141         else
       
   142             {
       
   143             server.Resume();  // Logon OK - start the server
       
   144             }
       
   145 
       
   146         User::WaitForRequest( stat ); // Wait for start or death
       
   147 
       
   148         // We can't use the 'exit reason' if the server paniced as this
       
   149         // is the panic 'reason' and may be '0' which cannot be distinguished
       
   150         // from KErrNone
       
   151         err = (server.ExitType() == EExitPanic)? KErrGeneral : stat.Int();
       
   152 
       
   153         // We can close the handle now
       
   154         server.Close();        
       
   155         }
       
   156 
       
   157     return err;
       
   158     }
       
   159 
       
   160 //////////////////////////////////////////////////////////////////////////////////////////////////
       
   161 /////////////////////////////        RTestFeatMgrSession          ////////////////////////////////
       
   162 //////////////////////////////////////////////////////////////////////////////////////////////////
       
   163 
       
   164 class RTestFeatMgrSession : public RSessionBase
       
   165     {
       
   166 public: 
       
   167     TInt Connect();
       
   168     void Close();
       
   169     TInt SendReceive(TInt aFunction);
       
   170     TInt SendReceive(TInt aFunction, const TIpcArgs& aArgs);
       
   171 
       
   172 private:
       
   173     TInt DoCreateSession();
       
   174     };
       
   175     
       
   176 TInt RTestFeatMgrSession::Connect()
       
   177     {
       
   178     TInt err = DoCreateSession();
       
   179     if(err != KErrNone && err != KErrAlreadyExists)
       
   180         {
       
   181         Close();
       
   182         }
       
   183     return err;
       
   184     }
       
   185 
       
   186 void RTestFeatMgrSession::Close()
       
   187     {
       
   188     RSessionBase::Close();
       
   189     }
       
   190 
       
   191 TInt RTestFeatMgrSession::SendReceive(TInt aFunction)
       
   192     {
       
   193     return RSessionBase::SendReceive(aFunction);    
       
   194     }
       
   195     
       
   196 TInt RTestFeatMgrSession::SendReceive(TInt aFunction, const TIpcArgs& aArgs)
       
   197     {
       
   198     return RSessionBase::SendReceive(aFunction, aArgs); 
       
   199     }
       
   200 
       
   201 TInt RTestFeatMgrSession::DoCreateSession()
       
   202     {
       
   203     const TInt KRetry( 2 );
       
   204     // Try this twice
       
   205     TInt retry( KRetry );
       
   206     TInt err( KErrNone );
       
   207 
       
   208     while ( retry > 0 )
       
   209         {
       
   210         // Try to create a FeatMgr Server session
       
   211         err = CreateSession(KServerProcessName, 
       
   212                             TVersion(KServerVersionMajor, KServerVersionMinor, KServerVersionBuild), 
       
   213                             KDefaultAsyncSlots);
       
   214 
       
   215         if ( err != KErrNotFound && err != KErrServerTerminated )
       
   216             {
       
   217             // KErrNone or unrecoverable error
       
   218             retry = 0;
       
   219             }
       
   220         else
       
   221             {
       
   222             // Return code was KErrNotFound or KErrServerTerminated.
       
   223             // Try to start a new FeatMgr Server
       
   224             err = StartFeatMgrServer();
       
   225 
       
   226             if ( err != KErrNone && err != KErrAlreadyExists )
       
   227                 {
       
   228                 // Unrecoverable error
       
   229                 retry = 0;
       
   230                 }
       
   231             }
       
   232             
       
   233         retry--;
       
   234         }
       
   235             
       
   236     return err;
       
   237     }
       
   238     
       
   239 void PrintIterationCount(TInt aIteration)
       
   240     {
       
   241     if((aIteration % 100) == 0)
       
   242         {
       
   243         TTime time;
       
   244         time.HomeTime();
       
   245         TDateTime dt = time.DateTime();
       
   246         TBuf<16> tbuf;
       
   247         tbuf.Format(_L("%02d:%02d:%02d.%06d"), dt.Hour(), dt.Minute(), dt.Second(), dt.MicroSecond());
       
   248         RDebug::Print(_L("-----[%S] Test iterations: %d\r\n"), &tbuf, aIteration);
       
   249         }
       
   250     }
       
   251 
       
   252 //Worker thread function.
       
   253 //It behaves as a malicious client. Connects to the FeatMgr server. In each test iteration generates some random values
       
   254 //for the function number, handle, IPC arguments. Then sends a command to the server using these
       
   255 //randomly generated values. If the server crashes and the thread function receives KErrServerTerminated error,
       
   256 //then the thread kills itself and the main thread will get KPanicCategory and KPanicCode as a reason for the
       
   257 //worker thread's death. The last set of randomly generated values will be stored in the memory, pointed by aData argument.
       
   258 TInt ThreadFunc1(void* aData)
       
   259     {
       
   260     __UHEAP_MARK;
       
   261     
       
   262     CTrapCleanup* tc = CTrapCleanup::New();
       
   263     TTEST(tc != NULL);
       
   264 
       
   265     TThreadData* p = static_cast <TThreadData*> (aData);
       
   266     TTEST(p != NULL);
       
   267     TThreadData& data = *p;
       
   268 
       
   269     RTestFeatMgrSession sess;
       
   270     TInt err = sess.Connect();
       
   271     TTEST2(err, KErrNone);
       
   272 
       
   273     while(++data.iIteration <= KTestIterCount)
       
   274         {
       
   275         RDebug::Print(_L("++++ %d\r\n"), data.iIteration);
       
   276         
       
   277         PrintIterationCount(data.iIteration);
       
   278         TIpcArgs args;
       
   279         data.iFunction = Math::Rand(data.iSeed) % (EFeatMgrSWIEnd + 1);//EFeatMgrSWIEnd - the last server message number (without resource checking IPCs))
       
   280         for(TInt i=0;i<KMaxMessageArguments;++i)
       
   281             {
       
   282             //Initialize arguments
       
   283             data.iArgType[i] = static_cast <TArgType> (Math::Rand(data.iSeed) % ELastArgType);
       
   284             switch(data.iArgType[i])
       
   285                 {
       
   286                 case EIntArgType:
       
   287                     data.iIntArg[i] = Math::Rand(data.iSeed) % 9711;
       
   288                     args.Set(i, data.iIntArg[i]);
       
   289                     break;
       
   290                 case ETextArgType:
       
   291                     {
       
   292                     TInt len = Math::Rand(data.iSeed) % KMaxDesArgLen;  
       
   293                     data.iTextArg[i].SetLength(len);
       
   294                     args.Set(i, &data.iTextArg[i]);
       
   295                     }
       
   296                     break;
       
   297                 case EBinArgType:
       
   298                     {
       
   299                     TInt len = Math::Rand(data.iSeed) % KMaxDesArgLen;  
       
   300                     data.iBinArg[i].SetLength(len);
       
   301                     args.Set(i, &data.iBinArg[i]);
       
   302                     }
       
   303                     break;
       
   304                 default:
       
   305                     User::Panic(KPanicCategory2, KPanicCode2);
       
   306                     break;
       
   307                 }
       
   308             }
       
   309         //Send arguments
       
   310         User::SetJustInTime(EFalse);
       
   311         TInt err = KErrNone;
       
   312         err = sess.SendReceive(data.iFunction, args);
       
   313         if(err == KErrServerTerminated)
       
   314             {
       
   315             User::Panic(KPanicCategory, KPanicCode);
       
   316             }
       
   317         User::SetJustInTime(ETrue);
       
   318         }
       
   319 
       
   320     sess.Close();
       
   321 
       
   322     delete tc;  
       
   323     
       
   324     __UHEAP_MARKEND;
       
   325     
       
   326     return KErrNone;        
       
   327     }
       
   328 
       
   329 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
   330 
       
   331 /**
       
   332 @SYMTestCaseID          PDS-EFM-CT-4065
       
   333 @SYMTestCaseDesc        
       
   334 @SYMTestPriority        High
       
   335 @SYMTestActions         
       
   336 @SYMTestExpectedResults Test must not fail
       
   337 @SYMDEF                 DEF144262
       
   338 */
       
   339 void BadClientTest()
       
   340     {
       
   341     TThreadData* p = new TThreadData;
       
   342     TEST(p != NULL);
       
   343     TThreadData& data = *p;
       
   344     data.iFunction = 0;
       
   345     TTime now;
       
   346     now.UniversalTime();
       
   347     data.iSeed = now.Int64();
       
   348     
       
   349     _LIT(KThreadName, "WorkThrd");
       
   350     
       
   351     for(data.iIteration=0;data.iIteration<KTestIterCount;++data.iIteration)
       
   352         {
       
   353         PrintIterationCount(data.iIteration);
       
   354         //Run the malicious client (one worker theread which will try to crash the FeatMgr server)
       
   355         RThread thread;
       
   356         TEST2(thread.Create(KThreadName, &ThreadFunc1, 0x2000, 0x1000, 0x10000, &data, EOwnerProcess), KErrNone);
       
   357         TRequestStatus status;
       
   358         thread.Logon(status);
       
   359         TEST2(status.Int(), KRequestPending);
       
   360         thread.Resume();
       
   361         User::WaitForRequest(status);
       
   362         User::SetJustInTime(ETrue); // enable debugger panic handling
       
   363         if(thread.ExitType() == EExitPanic)
       
   364             {
       
   365             if(thread.ExitReason() == KPanicCode)
       
   366                 {
       
   367                 TheTest.Printf(_L("##Server terminated!\r\n"));
       
   368                 TheTest.Printf(_L("##Iteration=%d, Function(hex)=%X, Handle=%d\r\n"), data.iIteration, data.iFunction);
       
   369                 for(TInt i=0;i<KMaxMessageArguments;++i)
       
   370                     {
       
   371                     switch(data.iArgType[i])
       
   372                         {
       
   373                         case EIntArgType:
       
   374                             TheTest.Printf(_L("##Arg %d, Integer, value=%d\r\n"), i, data.iIntArg[i]);
       
   375                             break;
       
   376                         case ETextArgType:
       
   377                             TheTest.Printf(_L("##Arg %d, Text,    length=%d\r\n"), i, data.iTextArg[i].Length());
       
   378                             break;
       
   379                         case EBinArgType:
       
   380                             TheTest.Printf(_L("##Arg %d, Binary,  length=%d\r\n"), i, data.iBinArg[i].Length());
       
   381                             break;
       
   382                         default:
       
   383                             TheTest.Printf(_L("##Arg %d, Invalid argument type: %d\r\n"), i, data.iArgType[i]);
       
   384                             break;
       
   385                         }
       
   386                     }
       
   387                 TEST(0);
       
   388                 }
       
   389             }
       
   390         thread.Close();
       
   391         }
       
   392     User::SetJustInTime(ETrue); // enable debugger panic handling
       
   393     delete p;
       
   394     }
       
   395 
       
   396 void DoTestsL()
       
   397     {
       
   398     //TODO: this test won't pass
       
   399     TheTest.Start(_L("@SYMTestCaseID:PDS-EFM-CT-4065 Bad client test"));
       
   400     BadClientTest();
       
   401     }
       
   402 
       
   403 TInt E32Main()
       
   404     {
       
   405     TheTest.Title();
       
   406     
       
   407     CTrapCleanup* tc = CTrapCleanup::New();
       
   408     TheTest(tc != NULL);
       
   409     
       
   410     __UHEAP_MARK;
       
   411     
       
   412     TRAPD(err, DoTestsL());
       
   413     DestroyTestEnv();
       
   414     TEST2(err, KErrNone);
       
   415 
       
   416     __UHEAP_MARKEND;
       
   417     
       
   418     TheTest.End();
       
   419     TheTest.Close();
       
   420     
       
   421     delete tc;
       
   422 
       
   423     User::Heap().Check();
       
   424     return KErrNone;
       
   425     }