1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/runtests/runtests.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,790 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// f32\runtests\runtests.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include <e32std.h>
1.22 +#include <e32std_private.h>
1.23 +#include <e32def_private.h>
1.24 +#include <e32svr.h>
1.25 +#include <e32ldr.h>
1.26 +#include <hal.h>
1.27 +#include "f32file.h"
1.28 +#include "f32dbg.h"
1.29 +#include "runtests.h"
1.30 +#include <u32hal.h>
1.31 +
1.32 +#define __PANIC(r) Panic(__LINE__,r)
1.33 +
1.34 +//#define _RUN_FOREVER_
1.35 +//#define _PANIC_ON_FAILURE_
1.36 +
1.37 +const TInt KDefaultTimeout=1200; // 20 minutes
1.38 +const TInt KBackgroundTimeout=3000000; // 3 seconds
1.39 +const TInt KDestroyTimeout=1000000; // 1 second
1.40 +
1.41 +_LIT(KLitBackslash,"\\");
1.42 +_LIT(KDebugMessage, "Testing finished, and the system will be panicked");
1.43 +#ifdef __EPOC32__
1.44 +_LIT(KLitDefaultTestPath,"Z:\\TEST");
1.45 +#else
1.46 +_LIT(KLitDefaultTestPath,"");
1.47 +#endif
1.48 +
1.49 +#ifdef _DEBUG
1.50 +_LIT(KBuildType, "UDEB");
1.51 +#else
1.52 +_LIT(KBuildType, "UREL");
1.53 +#endif
1.54 +
1.55 +typedef RArray<TUint> RProcIdList;
1.56 +
1.57 +GLDEF_D TPath TheTestPath = KLitDefaultTestPath();
1.58 +GLDEF_D RFs TheFs;
1.59 +GLDEF_D RLoader TheLoaderSession;
1.60 +GLDEF_D TDesC8* TheTestList;
1.61 +GLDEF_D RTimer TheTimer;
1.62 +GLDEF_D TBuf<256> TheProcessCommand=KNullDesC();
1.63 +GLDEF_D TInt TheTimeOut = KDefaultTimeout;
1.64 +GLDEF_D TInt TheCurrentProcessList;
1.65 +GLDEF_D RProcIdList ProcLists[2];
1.66 +GLDEF_D RTimer IdleWaitTimer;
1.67 +GLDEF_D RTimer DestructionTimer;
1.68 +GLDEF_D RProperty CurrTest;
1.69 +TBool ShowTimings = 0;
1.70 +TInt TickPeriod = 15625;
1.71 +TBool CleanUpProcesses = EFalse;
1.72 +
1.73 +#ifdef _ENABLE_BTRACE_ANALYSIS_
1.74 +
1.75 +// BTrace analysis forward declarations
1.76 +const TInt KDefaultBTraceLevel = 0;
1.77 +TBool BtraceAnalysis = EFalse;
1.78 +TInt BTraceAnalysisLevel;
1.79 +TInt BTraceAnalyseSetup();
1.80 +void BTraceAnalyseEnd();
1.81 +void BTraceAnalyse(TInt aAnalysisLevel);
1.82 +
1.83 +#endif //_ENABLE_BTRACE_ANALYSIS_
1.84 +
1.85 +_LIT(KLitPanicCategory,"RUNTESTS-");
1.86 +_LIT(KLitLogPreamble,"RUNTESTS: ");
1.87 +
1.88 +void LogMsg(TRefByValue<const TDesC> aFmt,...);
1.89 +
1.90 +void DisableSimulatedFailure()
1.91 + {
1.92 + // Turn off simulated failure mechanisms for all base servers
1.93 + TheFs.SetAllocFailure(KAllocFailureOff); // F32 heap failure
1.94 + TheFs.SetErrorCondition(KErrNone, 0); // F32 other failure
1.95 + TheLoaderSession.DebugFunction(ELoaderDebug_SetHeapFail, 0, 0, 0); // Loader heap failure
1.96 + TheLoaderSession.DebugFunction(ELoaderDebug_SetRFsFail, KErrNone, 0, 0); // Loader RFs failure
1.97 +
1.98 + // make sure kernel heap debug is off
1.99 + __KHEAP_TOTAL_RESET;
1.100 + }
1.101 +
1.102 +GLDEF_C void Panic(TInt aLine, TInt aReason)
1.103 + {
1.104 + TBuf<16> cat=KLitPanicCategory();
1.105 + cat.AppendNum(aLine);
1.106 + User::Panic(cat,aReason);
1.107 + }
1.108 +
1.109 +TInt CloseAndWait(RHandleBase aH, TRequestStatus *aN = NULL)
1.110 + {
1.111 + TRequestStatus tempS;
1.112 + if(!aN)
1.113 + {
1.114 + // Create a destruction notifier if none was supplied.
1.115 + aH.NotifyDestruction(tempS);
1.116 + aN = &tempS;
1.117 + }
1.118 + if (*aN!=KRequestPending)
1.119 + {
1.120 + User::WaitForRequest(*aN);
1.121 + aH.Close();
1.122 + return KErrNoMemory;
1.123 + }
1.124 + TRequestStatus t;
1.125 + DestructionTimer.After(t, KDestroyTimeout);
1.126 + aH.Close();
1.127 + User::WaitForRequest(*aN, t);
1.128 + if (*aN != KRequestPending)
1.129 + {
1.130 + DestructionTimer.Cancel();
1.131 + User::WaitForRequest(t);
1.132 + return KErrNone;
1.133 + }
1.134 + User::CancelMiscNotifier(*aN);
1.135 + User::WaitForRequest(*aN);
1.136 + return KErrTimedOut;
1.137 + }
1.138 +
1.139 +void CloseWaitAndWarn(RHandleBase aH, TRequestStatus *aN = NULL)
1.140 + {
1.141 + TFullName fn(aH.FullName());
1.142 + TInt r = CloseAndWait(aH, aN);
1.143 + if (r == KErrNoMemory)
1.144 + LogMsg(_L("WARNING OOM checking destruction of %S"), &fn);
1.145 + else if (r == KErrTimedOut)
1.146 + LogMsg(_L("ERROR Destruction of %S timed out"), &fn);
1.147 + }
1.148 +
1.149 +TInt InitIdleWait()
1.150 + {
1.151 + TInt r = IdleWaitTimer.CreateLocal();
1.152 + if (r!=KErrNone)
1.153 + return r;
1.154 + return KErrNone;
1.155 + }
1.156 +
1.157 +void WaitForIdle()
1.158 + {
1.159 + TRequestStatus idle_req;
1.160 + TRequestStatus timer_req;
1.161 + IdleWaitTimer.After(timer_req, KBackgroundTimeout);
1.162 + User::NotifyOnIdle(idle_req);
1.163 + User::WaitForRequest(idle_req, timer_req);
1.164 + if (idle_req != KRequestPending)
1.165 + {
1.166 + IdleWaitTimer.Cancel();
1.167 + User::WaitForRequest(timer_req);
1.168 + }
1.169 + else
1.170 + {
1.171 + User::CancelMiscNotifier(idle_req);
1.172 + User::WaitForRequest(idle_req);
1.173 + LogMsg(_L("WARNING Excessive Background Activity Detected"));
1.174 + }
1.175 + }
1.176 +
1.177 +TBool IntentionallyPersistent(RProcess aProcess)
1.178 + {
1.179 + TInt v;
1.180 + TInt r = RProperty::Get(aProcess.SecureId(), KRuntestsIntentionalPersistenceKey, v);
1.181 + if (r==KErrNone && TUint(v)==KRuntestsIntentionalPersistenceValue)
1.182 + return ETrue;
1.183 + return EFalse;
1.184 + }
1.185 +
1.186 +TInt GetProcessListThread(TAny* a)
1.187 + {
1.188 + RProcIdList& pl = *(RProcIdList*)a;
1.189 + TFindProcess fp(_L("*"));
1.190 + TFullName fn;
1.191 + TInt r = KErrNone;
1.192 + while (r==KErrNone && fp.Next(fn)==KErrNone)
1.193 + {
1.194 + RProcess p;
1.195 + r = p.Open(fp, EOwnerThread);
1.196 + if (r==KErrNone)
1.197 + {
1.198 + TUint id = (TUint)p.Id();
1.199 + r = pl.Append(id);
1.200 + p.Close();
1.201 + }
1.202 + }
1.203 + return r;
1.204 + }
1.205 +
1.206 +TInt GetProcessList(RProcIdList& aList)
1.207 + {
1.208 + aList.Reset();
1.209 + RThread t;
1.210 + TRequestStatus s;
1.211 + TInt r = t.Create(KNullDesC, &GetProcessListThread, 0x1000, NULL, &aList);
1.212 + if (r==KErrNone)
1.213 + {
1.214 + t.Logon(s);
1.215 + t.SetPriority(EPriorityAbsoluteHigh);
1.216 + if (s==KRequestPending)
1.217 + t.Resume();
1.218 + User::WaitForRequest(s);
1.219 + r=s.Int();
1.220 + if (t.ExitType()==EExitPending)
1.221 + {
1.222 + t.Kill(0);
1.223 + WaitForIdle();
1.224 + }
1.225 + else if (t.ExitType()!=EExitKill)
1.226 + {
1.227 + r = -99;
1.228 + }
1.229 + CloseWaitAndWarn(t);
1.230 + }
1.231 + aList.Sort();
1.232 + return r;
1.233 + }
1.234 +
1.235 +TBool ParseNumber(TLex& aLex, TUint& aNumber, TBool isTime)
1.236 + {
1.237 + TPtrC numberDes = aLex.NextToken();
1.238 + TInt len = numberDes.Length();
1.239 + if (len == 0)
1.240 + {
1.241 + return EFalse;
1.242 + }
1.243 +
1.244 + aNumber = 0;
1.245 + TInt magnitude = 1;
1.246 + TChar c = numberDes[len-1];
1.247 + if (isTime)
1.248 + {
1.249 + switch (c)
1.250 + {
1.251 + case 'h':
1.252 + case 'H':
1.253 + len -= 1;
1.254 + magnitude = 3600;
1.255 + break;
1.256 +
1.257 + case 'm':
1.258 + case 'M':
1.259 + len -= 1;
1.260 + /*FALLTHRU*/
1.261 + default:
1.262 + magnitude = 60;
1.263 + break;
1.264 +
1.265 + case 's':
1.266 + case 'S':
1.267 + len -= 1;
1.268 + magnitude = 1;
1.269 + break;
1.270 + }
1.271 + }
1.272 +
1.273 + for (TInt i = len-1; i >= 0; --i)
1.274 + {
1.275 + c = numberDes[i];
1.276 + if (c < '0' || c > '9')
1.277 + __PANIC(KErrArgument);
1.278 + aNumber += ((TInt)c-'0')*magnitude;
1.279 + magnitude *= 10;
1.280 + }
1.281 +
1.282 + return ETrue;
1.283 + }
1.284 +
1.285 +void GetTimeOut(TLex& aLex)
1.286 +//
1.287 +//
1.288 +//
1.289 + {
1.290 + TheTimeOut = KDefaultTimeout;
1.291 + TUint timeOut = 0;
1.292 + if (ParseNumber(aLex, timeOut, ETrue))
1.293 + {
1.294 + TheTimeOut = timeOut;
1.295 + }
1.296 + }
1.297 +
1.298 +#ifdef _ENABLE_BTRACE_ANALYSIS_
1.299 +
1.300 +void GetAnalysisLevel(TLex& aLex)
1.301 + {
1.302 + BTraceAnalysisLevel = KDefaultBTraceLevel;
1.303 + TUint level;
1.304 + if (ParseNumber(aLex, level, EFalse))
1.305 + {
1.306 + BTraceAnalysisLevel = level;
1.307 + }
1.308 + }
1.309 +#endif //_ENABLE_BTRACE_ANALYSIS_
1.310 +
1.311 +void LogMsg(TRefByValue<const TDesC> aFmt,...)
1.312 + {
1.313 + VA_LIST list;
1.314 + VA_START(list,aFmt);
1.315 + TBuf<0x100> buf=KLitLogPreamble();
1.316 + buf.AppendFormatList(aFmt,list);
1.317 + RDebug::Print(_L("%S"),&buf);
1.318 + }
1.319 +
1.320 +_LIT(KLitError, "Error ");
1.321 +TBool LogProcess(TUint aId, TBool aInit)
1.322 + {
1.323 + TFullName pn;
1.324 + TFileName fn;
1.325 + RProcess p;
1.326 + TBool killed = EFalse;
1.327 + TInt r = p.Open(TProcessId(aId));
1.328 + if (r==KErrNone)
1.329 + {
1.330 + if (IntentionallyPersistent(p))
1.331 + {
1.332 + p.Close();
1.333 + return killed;
1.334 + }
1.335 + pn = p.FullName();
1.336 + fn = p.FileName();
1.337 + if (!aInit && CleanUpProcesses && p.ExitType()==EExitPending)
1.338 + {// p is a left over process so terminate it.
1.339 + killed = ETrue;
1.340 + TRequestStatus status;
1.341 + p.Logon(status);
1.342 + p.Kill(KErrNone); // Kill with KErrNone to suppress extra debug output from kernel.
1.343 + User::WaitForRequest(status);
1.344 + CloseAndWait(p);
1.345 + }
1.346 + else
1.347 + {
1.348 + p.Close();
1.349 + }
1.350 + }
1.351 + else
1.352 + {
1.353 + pn = KLitError;
1.354 + pn.AppendNum(r);
1.355 + }
1.356 + if (aInit)
1.357 + LogMsg(_L("Running process id=%d: %S (%S)"),aId,&pn,&fn);
1.358 + else
1.359 + {
1.360 + if(killed)
1.361 + LogMsg(_L("ERROR Leftover process was killed id=%d: %S (%S)"),aId,&pn,&fn);
1.362 + else
1.363 + LogMsg(_L("ERROR Leftover process id=%d: %S (%S)"),aId,&pn,&fn);
1.364 + }
1.365 + return killed;
1.366 + }
1.367 +
1.368 +void ListProcesses()
1.369 + {
1.370 + RProcIdList& cur_list = ProcLists[TheCurrentProcessList];
1.371 + TInt cc = cur_list.Count();
1.372 + TInt ci;
1.373 + for (ci=0; ci<cc; ++ci)
1.374 + {
1.375 + LogProcess(cur_list[ci], ETrue);
1.376 + }
1.377 + }
1.378 +
1.379 +void CheckProcesses()
1.380 + {
1.381 + RProcIdList& cur_list = ProcLists[TheCurrentProcessList];
1.382 + RProcIdList& new_list = ProcLists[1-TheCurrentProcessList];
1.383 + TInt r = GetProcessList(new_list);
1.384 + if (r!=KErrNone)
1.385 + {
1.386 + LogMsg(_L("WARNING Problem getting process list, error %d"),r);
1.387 + return;
1.388 + }
1.389 +
1.390 + TInt cc = cur_list.Count();
1.391 + TInt nc = new_list.Count();
1.392 + TInt ci = 0;
1.393 + TInt ni = 0;
1.394 + while (ci<cc || ni<nc)
1.395 + {
1.396 + TUint id1=0;
1.397 + TUint id2=0;
1.398 + if (ci<cc)
1.399 + id1 = cur_list[ci];
1.400 + if (ni<nc)
1.401 + id2 = new_list[ni];
1.402 + if (ci==cc)
1.403 + {
1.404 + // extra process has appeared so kill it and output an error message.
1.405 + if (LogProcess(id2, EFalse))
1.406 + {// Remove from list as we don't want it to be considered as vanished when the next test completes.
1.407 + new_list.Remove(ni);
1.408 + nc--;
1.409 + }
1.410 + else
1.411 + {// Extra process was left running so just move onto the next one.
1.412 + ni++;
1.413 + }
1.414 + }
1.415 + else if (ni<nc && id1==id2)
1.416 + {
1.417 + // process remains
1.418 + ++ci, ++ni;
1.419 + }
1.420 + else
1.421 + {
1.422 + // process has disappeared
1.423 + LogMsg(_L("WARNING Vanished process, id=%d"),id1);
1.424 + ++ci;
1.425 + }
1.426 + }
1.427 +
1.428 + // current list = new list
1.429 + TheCurrentProcessList = 1 - TheCurrentProcessList;
1.430 +
1.431 + // throw away the old list
1.432 + cur_list.Reset();
1.433 + }
1.434 +
1.435 +_LIT8 (KLitRemark,"REM");
1.436 +_LIT8 (KLitAtRemark,"@REM");
1.437 +
1.438 +void ProcessLine(const TDesC8& aLine)
1.439 + {
1.440 + TLex8 lex(aLine);
1.441 + TPtrC8 testname=lex.NextToken();
1.442 + if (testname.Length()>=2 && testname[0]=='/' && testname[1]=='/')
1.443 + return;
1.444 + // ignore this line if it begins with rem or @rem
1.445 + if (testname.CompareF(KLitRemark) == 0 || testname.CompareF(KLitAtRemark) == 0)
1.446 + return;
1.447 + TFileName testnameU;
1.448 + testnameU.Copy(testname);
1.449 + TFileName fullpathname;
1.450 + if (testnameU.Locate(TChar('\\'))==KErrNotFound)
1.451 + fullpathname=TheTestPath;
1.452 + fullpathname+=testnameU;
1.453 + if (testname.Locate(TChar('.'))==KErrNotFound)
1.454 + fullpathname+=_L(".EXE");
1.455 + TInt r;
1.456 +
1.457 + RFile file;
1.458 + r=file.Open(TheFs,fullpathname,EFileRead);
1.459 + if (r!=KErrNone)
1.460 + {
1.461 + // Remove path to let loader locate exe
1.462 + fullpathname = fullpathname.Mid(fullpathname.LocateReverse('\\')+1);
1.463 + }
1.464 + else
1.465 + file.Close();
1.466 +
1.467 + RProcess p;
1.468 + if(TheProcessCommand==KNullDesC)
1.469 + {
1.470 + TheProcessCommand.Copy(lex.Remainder());
1.471 + r=p.Create(fullpathname, TheProcessCommand);
1.472 + TheProcessCommand=KNullDesC();
1.473 + }
1.474 + else
1.475 + r=p.Create(fullpathname, TheProcessCommand);
1.476 + if (r!=KErrNone)
1.477 + {
1.478 + LogMsg(_L("Test %S ERROR Could not load file, error %d"),&fullpathname,r);
1.479 + return;
1.480 + }
1.481 + else
1.482 + {
1.483 + LogMsg(_L("Started test %S"),&fullpathname);
1.484 + }
1.485 + TRequestStatus ds;
1.486 + p.NotifyDestruction(ds); // allocate the destruction notifier early so that it doesn't get flagged as a leak by kernel heap checking in e.g., efile (DEF133800)
1.487 + CurrTest.Set(p.FileName());
1.488 + User::After(100000); // allow latency measurements to be output
1.489 + p.SetJustInTime(EFalse); // we don't want the automatic test run to be halted by the debugger
1.490 + TRequestStatus ps;
1.491 + p.Rendezvous(ps);
1.492 + TInt time_remain = TheTimeOut;
1.493 + TRequestStatus ts;
1.494 + TUint start = User::TickCount();
1.495 + p.Resume();
1.496 + TBool persist = EFalse;
1.497 + TBool timer_running = EFalse;
1.498 + FOREVER
1.499 + {
1.500 + TInt nsec = Min(time_remain, 1800);
1.501 + if (!timer_running)
1.502 + TheTimer.After(ts, nsec*1000000);
1.503 + timer_running = ETrue;
1.504 + User::WaitForRequest(ps,ts);
1.505 + if (ps!=KRequestPending)
1.506 + {
1.507 + if (p.ExitType()==EExitPending)
1.508 + {
1.509 + // rendezvous completed but process not terminated
1.510 + if (!IntentionallyPersistent(p))
1.511 + {
1.512 + // not persistent - wait for process to terminate
1.513 + p.Logon(ps);
1.514 + continue;
1.515 + }
1.516 + persist = ETrue;
1.517 + }
1.518 + break;
1.519 + }
1.520 + timer_running = EFalse;
1.521 + time_remain -= nsec;
1.522 + if (time_remain==0)
1.523 + {
1.524 + LogMsg(_L("Going to kill test %S: it's taken %u seconds, which is too long"),&fullpathname,TheTimeOut);
1.525 + p.Kill(0);
1.526 + User::WaitForRequest(ps);
1.527 + p.Logon(ps);
1.528 + User::WaitForRequest(ps);
1.529 +
1.530 + CloseWaitAndWarn(p, &ds);
1.531 + RDebug::Print(_L("\n"));
1.532 + LogMsg(_L("Test %S TIMEOUT"),&fullpathname);
1.533 + return;
1.534 + }
1.535 + else
1.536 + {
1.537 + LogMsg(_L("Taken %u seconds so far"),TheTimeOut-time_remain);
1.538 + }
1.539 + }
1.540 + TUint end = User::TickCount();
1.541 + if(timer_running)
1.542 + {
1.543 + TheTimer.Cancel();
1.544 + User::WaitForRequest(ts);
1.545 + }
1.546 +
1.547 +#ifdef _ENABLE_BTRACE_ANALYSIS_
1.548 + //
1.549 + //
1.550 + //
1.551 + if (BtraceAnalysis)
1.552 + {// Analyse BTrace buffer
1.553 + BTraceAnalyse(BTraceAnalysisLevel);
1.554 + }
1.555 +#endif //_ENABLE_BTRACE_ANALYSIS_
1.556 +
1.557 + TBuf<32> exitCat=p.ExitCategory();
1.558 + TExitType exitType=p.ExitType();
1.559 + TInt exitReason=p.ExitReason();
1.560 + if (persist || (exitType==EExitKill && exitReason==KErrNone))
1.561 + {
1.562 + TUint time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000);
1.563 + if(ShowTimings)
1.564 + {
1.565 + LogMsg(_L("Test %S OK - Seconds Taken: %u"),&fullpathname, time);
1.566 + }
1.567 + else
1.568 + {
1.569 + LogMsg(_L("Test %S OK"),&fullpathname);
1.570 + }
1.571 + if (persist)
1.572 + {
1.573 + // We do not need this destruction notifier so cancel it.
1.574 + User::CancelMiscNotifier(ds);
1.575 + User::WaitForRequest(ds);
1.576 +
1.577 + p.Close();
1.578 + }
1.579 + else
1.580 + {
1.581 + CloseWaitAndWarn(p, &ds);
1.582 + }
1.583 + return;
1.584 + }
1.585 + LogMsg(_L("Test %S FAIL - Exit code %d,%d,%S"),&fullpathname,exitType,exitReason,&exitCat);
1.586 + CloseWaitAndWarn(p, &ds);
1.587 +#if defined(_PANIC_ON_FAILURE_)
1.588 + __PANIC(KErrGeneral);
1.589 +#endif
1.590 + }
1.591 +
1.592 +void ProcessTestList()
1.593 + {
1.594 + TUint start = User::TickCount();
1.595 +
1.596 + TLex8 llex(*TheTestList);
1.597 + while(!llex.Eos())
1.598 + {
1.599 + llex.SkipSpace();
1.600 + llex.Mark();
1.601 + while(!llex.Eos() && llex.Peek()!='\n' && llex.Peek()!='\r')
1.602 + llex.Inc();
1.603 + TPtrC8 line=llex.MarkedToken();
1.604 + if (line.Length()!=0)
1.605 + ProcessLine(line);
1.606 +
1.607 + // allow cleanup to complete before starting the next test
1.608 + WaitForIdle();
1.609 +
1.610 + // make sure simulated failure is off
1.611 + DisableSimulatedFailure();
1.612 +
1.613 + // check for leftover processes
1.614 + CheckProcesses();
1.615 +
1.616 + // Reset the demand paging cache to its default size.
1.617 + UserSvr::HalFunction(EHalGroupVM,EVMHalSetCacheSize, 0, 0);
1.618 + }
1.619 +
1.620 + TUint end = User::TickCount();
1.621 + TUint time = TUint((TUint64)(end-start)*(TUint64)TickPeriod/(TUint64)1000000);
1.622 + LogMsg(_L("Elapsed Seconds: %u"), time);
1.623 + }
1.624 +
1.625 +void Help()
1.626 + {
1.627 + RDebug::Print(_L("Runtests test list [-x where tests are] [-d drive letter to test] [-t timeout] [-p] [-st] [-c]"));
1.628 + RDebug::Print(_L("where -p sets runtests to be system permanent, -st enables timing information,"));
1.629 + RDebug::Print(_L("-c enables left over processes to be cleaned up"));
1.630 + }
1.631 +
1.632 +GLDEF_C TInt E32Main()
1.633 + {
1.634 + HAL::Get(HAL::ESystemTickPeriod, TickPeriod);
1.635 + RThread().SetPriority(EPriorityAbsoluteHigh);
1.636 + TBuf<0x100> cmd;
1.637 + User::CommandLine(cmd);
1.638 + TFileName thisfile=RProcess().FileName();
1.639 + TLex lex(cmd);
1.640 + TPtrC token=lex.NextToken();
1.641 + if (token.MatchF(thisfile)==0)
1.642 + {
1.643 + token.Set(lex.NextToken());
1.644 + }
1.645 + if (token.Length()==0)
1.646 + {// __PANIC(0);
1.647 + Help();
1.648 + return 0;
1.649 + }
1.650 + TFileName listfilename=token;
1.651 + while (!lex.Eos())
1.652 + {
1.653 + token.Set(lex.NextToken());
1.654 + if (token.Length()==0)
1.655 + break; // ignore trailing whitespace
1.656 + else if (token==_L("-x"))
1.657 + {
1.658 + token.Set(lex.NextToken());
1.659 + TheTestPath = token;
1.660 + }
1.661 + else if (token==_L("-d"))
1.662 + {
1.663 + token.Set(lex.NextToken());
1.664 + TheProcessCommand = token;
1.665 + }
1.666 + else if (token==_L("-t"))
1.667 + {
1.668 + GetTimeOut(lex);
1.669 + }
1.670 + else if (token==_L("-p"))
1.671 + {
1.672 + User::SetCritical(User::ESystemPermanent);
1.673 + }
1.674 + else if (token==_L("-st"))
1.675 + ShowTimings = 1;
1.676 +
1.677 +#ifdef _ENABLE_BTRACE_ANALYSIS_
1.678 + else if (token == _L("-a"))
1.679 + {
1.680 + BtraceAnalysis = ETrue;
1.681 + GetAnalysisLevel(lex);
1.682 + TInt r = BTraceAnalyseSetup();
1.683 + if (r != KErrNone)
1.684 + {
1.685 + RDebug::Print(_L("ERROR - Couldn't open BTrace driver (Code %d)"), r);
1.686 + return 0;
1.687 + }
1.688 + }
1.689 +#endif //_ENABLE_BTRACE_ANALYSIS_
1.690 +
1.691 + else if (token == _L("-c"))
1.692 + CleanUpProcesses = ETrue;
1.693 + else
1.694 + {
1.695 + RDebug::Print(_L("Unknown option %S"), &token);
1.696 + Help();
1.697 + return 0;
1.698 + }
1.699 + }
1.700 +
1.701 + RDebug::Print(_L("TPTT= %S \n"), &TheProcessCommand);
1.702 + RDebug::Print(_L("TTL= %S \n"), &listfilename);
1.703 + RDebug::Print(_L("TTP= %S \n"), &TheTestPath);
1.704 + RDebug::Print(_L("TO= %d seconds\n"), TheTimeOut);
1.705 +
1.706 + TInt l=TheTestPath.Length();
1.707 + if (l > 0 && TheTestPath[l-1]!='\\')
1.708 + TheTestPath+=KLitBackslash;
1.709 + if (listfilename.Locate(TChar('\\'))==KErrNotFound)
1.710 + listfilename.Insert(0,TheTestPath);
1.711 + TInt r=TheFs.Connect();
1.712 + if (r!=KErrNone)
1.713 + __PANIC(r);
1.714 + r = TheLoaderSession.Connect();
1.715 + if (r!=KErrNone)
1.716 + __PANIC(r);
1.717 + DisableSimulatedFailure();
1.718 + r=TheFs.SetSessionPath(_L("Z:\\test\\"));
1.719 + if (r!=KErrNone)
1.720 + __PANIC(r);
1.721 + r=TheTimer.CreateLocal();
1.722 + if (r!=KErrNone)
1.723 + __PANIC(r);
1.724 + RFile listfile;
1.725 + r=listfile.Open(TheFs,listfilename,EFileRead|EFileShareAny);
1.726 + if (r!=KErrNone)
1.727 + __PANIC(r);
1.728 + TInt listfilesize;
1.729 + r=listfile.Size(listfilesize);
1.730 + if (r!=KErrNone)
1.731 + __PANIC(r);
1.732 + HBufC8* pL=HBufC8::New(listfilesize);
1.733 + if (!pL)
1.734 + __PANIC(KErrNoMemory);
1.735 + TPtr8 ptr=pL->Des();
1.736 + TheTestList=pL;
1.737 + r=listfile.Read(ptr);
1.738 + if (r!=KErrNone)
1.739 + __PANIC(r);
1.740 + listfile.Close();
1.741 + LogMsg(_L("Running test script %S"),&listfilename);
1.742 + LogMsg(_L("Build %S"),&KBuildType);
1.743 + LogMsg(_L("Path to test %S"),&TheProcessCommand);
1.744 +
1.745 + r = RProperty::Define( KRuntestsCurrentTestKey,
1.746 + RProperty::EText,
1.747 + TSecurityPolicy(TSecurityPolicy::EAlwaysPass),
1.748 + TSecurityPolicy(RProcess().SecureId()),
1.749 + 512
1.750 + );
1.751 + if (r!=KErrNone && r!=KErrAlreadyExists)
1.752 + __PANIC(r);
1.753 + r = CurrTest.Attach(RProcess().SecureId(), KRuntestsCurrentTestKey);
1.754 + if (r!=KErrNone)
1.755 + __PANIC(r);
1.756 + r = CurrTest.Set(KNullDesC);
1.757 + if (r!=KErrNone)
1.758 + __PANIC(r);
1.759 +
1.760 + r = DestructionTimer.CreateLocal();
1.761 + if (r!=KErrNone)
1.762 + __PANIC(r);
1.763 + TheCurrentProcessList = 0;
1.764 + r = GetProcessList(ProcLists[0]);
1.765 + if (r!=KErrNone)
1.766 + __PANIC(r);
1.767 + ListProcesses();
1.768 + r = InitIdleWait();
1.769 + if (r!=KErrNone)
1.770 + __PANIC(r);
1.771 +#if defined(_RUN_FOREVER_)
1.772 + FOREVER
1.773 +#endif
1.774 + ProcessTestList();
1.775 + r = CurrTest.Set(KNullDesC);
1.776 + if (r!=KErrNone)
1.777 + __PANIC(r);
1.778 + CurrTest.Close();
1.779 + User::After(1000000); // allow latency measurements to be output before exiting
1.780 + LogMsg(_L("Completed test script %S"),&listfilename);
1.781 + TheLoaderSession.Close();
1.782 + TheFs.Close();
1.783 + TheTimer.Close();
1.784 + IdleWaitTimer.Close();
1.785 + DestructionTimer.Close();
1.786 +
1.787 +#ifdef _ENABLE_BTRACE_ANALYSIS_
1.788 + BTraceAnalyseEnd();
1.789 +#endif //_ENABLE_BTRACE_ANALYSIS_
1.790 + if(User::Critical()==User::ESystemPermanent)
1.791 + RDebug::Print(KDebugMessage);
1.792 + return KErrNone;
1.793 + }