mmtestenv/mmtestfw/recog/TestFrameworkRecog.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2003-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 <fbs.h>
       
    17 #include "TestFrameworkRecog.h"
       
    18 #include "TestFrameworkMain.h"
       
    19 
       
    20 #ifdef __WINS__
       
    21 #include <windows.h>	// for ExitProcess
       
    22 #endif // __WINS__
       
    23 
       
    24 GLREF_C void StartupL();
       
    25 const TInt KThreadStackSize=0x2000;			//  8KB
       
    26 const TInt KThreadInitHeapSize=0x1000;		//  4KB
       
    27 const TInt KThreadMaxHeapSize=0x1000000;	// 16MB
       
    28 const TInt KThreadStartupDelay=30000000;	// 30 seconds
       
    29 const TInt KMaxLineLength=256;				// max length of config file line
       
    30 _LIT(KLitConfigFileName, "C:\\MM\\AutorunTests.cfg");
       
    31 
       
    32 //
       
    33 
       
    34 CTestFrameworkRecognizer::CTestFrameworkRecognizer()
       
    35 	: CApaDataRecognizerType(KUidTestFrameworkRecognizer, CApaDataRecognizerType::ENormal)
       
    36 	{
       
    37 	}
       
    38 
       
    39 CTestFrameworkRecognizer::~CTestFrameworkRecognizer()
       
    40 	{
       
    41 	delete iTestActive;
       
    42 	}
       
    43 
       
    44 //
       
    45 // CApaDataRecognizerType stuff...
       
    46 TUint CTestFrameworkRecognizer::PreferredBufSize()
       
    47 	{
       
    48 	return 0;
       
    49 	}
       
    50 
       
    51 TDataType CTestFrameworkRecognizer::SupportedDataTypeL(TInt /*aIndex*/) const
       
    52 	{
       
    53 	return TDataType();
       
    54 	}
       
    55 
       
    56 void CTestFrameworkRecognizer::DoRecognizeL(const TDesC& /*aName*/, const TDesC8& /*aBuffer*/)
       
    57 	{
       
    58 	}
       
    59 
       
    60 //
       
    61 // Entry point of recognizer
       
    62 EXPORT_C CApaDataRecognizerType* CreateRecognizer()
       
    63 	{
       
    64 	CTestFrameworkRecognizer* self = new CTestFrameworkRecognizer();
       
    65 	TRAPD(err, self->DoCreateL());
       
    66 	return self;
       
    67 	}
       
    68 
       
    69 void CTestFrameworkRecognizer::DoCreateL()
       
    70 	{
       
    71 	// Open the config file
       
    72 	LoadConfigFileL(KLitConfigFileName);
       
    73 
       
    74 	// If the RUN_SCRIPT command is present in the config file, run each test in a separate thread
       
    75 	if (iRunScript)
       
    76 		{
       
    77 		// Create active object waiting on thread death
       
    78 		iTestActive = new(ELeave) CTestFrameworkRecogActive(iTestScriptArray);	// Takes ownership of iTestScriptArray
       
    79 
       
    80 		// Create the first test thread
       
    81 		iTestActive->CreateNextTestThread();
       
    82 		}
       
    83 	}
       
    84 
       
    85 void CTestFrameworkRecognizer::LoadConfigFileL(const TDesC& aFileName)
       
    86 	{
       
    87 	RFs fs;
       
    88 	User::LeaveIfError(fs.Connect());
       
    89 	CleanupClosePushL(fs);
       
    90 
       
    91 	TEntry entry;
       
    92 	User::LeaveIfError(fs.Entry(aFileName, entry));
       
    93 
       
    94 	RFile file;
       
    95 	User::LeaveIfError(file.Open(fs, aFileName, EFileRead));
       
    96 	CleanupClosePushL(file);
       
    97 
       
    98 	TInt size;
       
    99 	User::LeaveIfError(file.Size(size));
       
   100 	TUint8* fileData = (TUint8*)User::AllocLC(size);
       
   101 	TPtr8 ptr(fileData, 0, size);
       
   102 	User::LeaveIfError(file.Read(ptr));
       
   103 
       
   104 	iTestScriptArray = new(ELeave) CTestScriptArray(4);
       
   105 
       
   106 	// Process the config file
       
   107 	TLex8 lex(ptr);
       
   108 	while (!lex.Eos())
       
   109 		{
       
   110 		// skip any spaces
       
   111 		while (lex.Peek() == ' ')
       
   112 			lex.Inc();
       
   113 		// mark the start of the line
       
   114 		lex.Mark();
       
   115 		// move to the next
       
   116 		while (!lex.Eos() && lex.Peek() != '\n')
       
   117 			lex.Inc();
       
   118 		// step over \n
       
   119 		if (lex.Peek() == '\n' )
       
   120 			lex.Inc();
       
   121 
       
   122 		// Process line
       
   123 		TPtrC8 linePtr = lex.MarkedToken();
       
   124 		ProcessLineL(linePtr);
       
   125 		}
       
   126 	CleanupStack::PopAndDestroy(fileData);
       
   127 	CleanupStack::PopAndDestroy(2);	// file, fs
       
   128 	}
       
   129 
       
   130 void CTestFrameworkRecognizer::ProcessLineL(const TDesC8& aLine)
       
   131 	{
       
   132 	ASSERT(aLine.Length() <= KMaxLineLength);
       
   133 	TBuf<KMaxLineLength> buf;
       
   134 	buf.Copy(aLine);
       
   135 	if (buf.Find(_L("//"))==0)
       
   136 		{
       
   137 		// ignore comments
       
   138 		}
       
   139 	else
       
   140 		{
       
   141 		// Get the script path and startup delay
       
   142 		TLex lex(buf);
       
   143 		if (!iRunScript)
       
   144 			{
       
   145 			if (lex.NextToken().Compare(_L("RUN_SCRIPT")) == 0)
       
   146 				iRunScript = ETrue;
       
   147 			}
       
   148 		else
       
   149 			{
       
   150 			// Parse the parameters
       
   151 			TTestScriptInfo info;
       
   152 			info.iScriptPath = lex.NextToken();
       
   153 			info.iThreadStartupDelay = 0;
       
   154 
       
   155 			TPtrC token(lex.NextToken());
       
   156 			while (token.Length())
       
   157 				{
       
   158 				if (token[0] == '-')
       
   159 					{
       
   160 					info.iParams.Append(token);
       
   161 					info.iParams.Append(' ');
       
   162 					}
       
   163 				else
       
   164 					{
       
   165 					// Assume this to be the startup delay
       
   166 					TLex tokenLex(token);
       
   167 					User::LeaveIfError(tokenLex.Val(info.iThreadStartupDelay));
       
   168 					if (info.iThreadStartupDelay < 0)
       
   169 						info.iThreadStartupDelay = 0;
       
   170 					}
       
   171 				token.Set(lex.NextToken());
       
   172 				}
       
   173 
       
   174 			// Add the script info
       
   175 			if (info.iScriptPath.Length())
       
   176 				iTestScriptArray->AppendL(info);
       
   177 			}
       
   178 		}
       
   179 	}
       
   180 
       
   181 //
       
   182 // CTestFrameworkRecogActive
       
   183 CTestFrameworkRecogActive::CTestFrameworkRecogActive(CTestScriptArray* aTestScriptArray)
       
   184 	: CActive(EPriorityStandard), iTestScriptArray(aTestScriptArray)
       
   185 	{
       
   186 	CActiveScheduler::Add(this);
       
   187 	iCurrentScript = -1;
       
   188 	}
       
   189 
       
   190 CTestFrameworkRecogActive::~CTestFrameworkRecogActive()
       
   191 	{
       
   192 	delete iTestScriptArray;
       
   193 	}
       
   194 
       
   195 TInt CTestFrameworkRecogActive::CreateNextTestThread()
       
   196 	{
       
   197 	// Create the next test in a separate thread
       
   198 	iCurrentScript++;
       
   199 	RThread thread;
       
   200 	TBuf<16> threadName;
       
   201 	threadName.Format(_L("TFR_THREAD_%d"), iCurrentScript);
       
   202 
       
   203 	TInt err = thread.Create(threadName, &StartTestThreadFn, KThreadStackSize,
       
   204 							 &User::Heap(), this);
       
   205 
       
   206 	if (err == KErrNone)
       
   207 		{
       
   208 		thread.Logon(iStatus);
       
   209 		thread.Resume();
       
   210 		SetActive();
       
   211 		}
       
   212 	return err;
       
   213 	}
       
   214 
       
   215 void CTestFrameworkRecogActive::DoCancel()
       
   216 	{
       
   217 	}
       
   218 
       
   219 void CTestFrameworkRecogActive::RunL()
       
   220 	{
       
   221 	// This will run when the thread created in CreateNextTestThreadL dies
       
   222 	//
       
   223 	TInt err = KErrNone;
       
   224 	if (iCurrentScript < (iTestScriptArray->Count() - 1))
       
   225 		{
       
   226 		err = CreateNextTestThread();
       
   227 		}
       
   228 	else
       
   229 		{
       
   230 		// Tests finished
       
   231 		delete iTestScriptArray;
       
   232 		iTestScriptArray = NULL;
       
   233 #ifdef __WINS__
       
   234 		// Cause the emulator to exit
       
   235 		ExitProcess(0);
       
   236 #endif // __WINS__
       
   237 		}
       
   238 	}
       
   239 
       
   240 TInt CTestFrameworkRecogActive::StartTestThreadFn(TAny* aPtr)
       
   241 	{
       
   242 	CTestFrameworkRecogActive* self = static_cast<CTestFrameworkRecogActive*>(aPtr);
       
   243 	TRAPD(err, self->DoStartTestThreadL());
       
   244 	return err;
       
   245 	}
       
   246 
       
   247 void CTestFrameworkRecogActive::DoStartTestThreadL()
       
   248 	{
       
   249 	// Create the thread and wait until it's finished
       
   250 	RThread thread;
       
   251 	TBuf<16> threadName;
       
   252 	threadName.Format(_L("TESTFRMRECOG_%d"), iCurrentScript);
       
   253 
       
   254 	TInt err = thread.Create(threadName, &ThreadFunc, KThreadStackSize,
       
   255 							 &User::Heap(), this);
       
   256 
       
   257 	if (err == KErrNone)
       
   258 		{
       
   259 		RSemaphore sem;
       
   260 		err = sem.CreateGlobal(KRecogSemaphoreName, 0);
       
   261 		if (err == KErrAlreadyExists)
       
   262 			err = sem.OpenGlobal(KRecogSemaphoreName);
       
   263 		if (err == KErrNone)
       
   264 			{
       
   265 			// Start the thread and wait for it to signal us that it's finished
       
   266 			thread.Resume();
       
   267 			sem.Wait();
       
   268 			}
       
   269 		}
       
   270 	User::LeaveIfError(err);
       
   271 	}
       
   272 
       
   273 
       
   274 TInt CTestFrameworkRecogActive::ThreadFunc(TAny* aPtr)
       
   275 	{
       
   276 	CTrapCleanup* cleanup = CTrapCleanup::New(); // get clean-up stack
       
   277 	CTestFrameworkRecogActive* self = static_cast<CTestFrameworkRecogActive*>(aPtr);
       
   278 	TRAPD(err, self->DoThreadFuncL());
       
   279 	delete cleanup; // destroy clean-up stack
       
   280 	return err;
       
   281 	}
       
   282 
       
   283 void CTestFrameworkRecogActive::DoThreadFuncL()
       
   284 	{
       
   285 	// Run the test script, using filename held in iScriptPath
       
   286 	CActiveScheduler* scheduler=new(ELeave) CActiveScheduler;
       
   287 	CleanupStack::PushL(scheduler);
       
   288 	CActiveScheduler::Install(scheduler);
       
   289 
       
   290 // Hurricane emulator only - start all services which we require to run tests.
       
   291 // Future enhancement :- add these startups to TestUtils
       
   292 #if defined(__WINS__)
       
   293 	#ifndef EXCLUDE_FOR_UNITTEST
       
   294 	FbsStartup();
       
   295 	#endif // EXCLUDE_FOR_UNITTEST
       
   296 #endif
       
   297 
       
   298 	// Get the current script
       
   299 	const TTestScriptInfo& script = iTestScriptArray->At(iCurrentScript);
       
   300 
       
   301 	// Delay for several seconds to allow vital bits of the emulator to start up (window server bits)
       
   302 	User::After(script.iThreadStartupDelay);
       
   303 
       
   304 	// Format the parameter to be passed to the test framework
       
   305 	TFileName args;
       
   306 	if (script.iParams.Length())
       
   307 		{
       
   308 		// Add the params
       
   309 		args.Append(script.iParams);
       
   310 		args.Append(' ');
       
   311 		}
       
   312 	args.Append(script.iScriptPath);
       
   313 
       
   314 	// Run the script
       
   315 	CTestFrameworkMain* tester = CTestFrameworkMain::NewLC();
       
   316 	tester->StartTestingL(args);
       
   317 
       
   318 	CleanupStack::PopAndDestroy(2, scheduler);	// tester, scheduler
       
   319 	}
       
   320 
       
   321