loggingservices/eventlogger/test/src/test.cpp
branchRCL_3
changeset 10 31a8f755b7fe
parent 9 667e88a979d7
child 11 211563e4b919
equal deleted inserted replaced
9:667e88a979d7 10:31a8f755b7fe
     1 // Copyright (c) 2004-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 <bautils.h>
       
    17 #include "TEST.H"
       
    18 
       
    19 #undef test  //there is a "test" macro which hides "RTest test" declaration.
       
    20 
       
    21 _LIT(KHelperExeName, "t_LogHiCapHelper.exe");
       
    22 
       
    23 //======================================================================================================
       
    24 
       
    25 TPtrC FileName(const TText* aFile)
       
    26     {
       
    27     TPtrC p(aFile);
       
    28     TInt ix=p.LocateReverse('\\');
       
    29     if (ix<0)
       
    30         ix=p.LocateReverse('/');
       
    31     if (ix>=0)
       
    32         p.Set(p.Mid(1+ix));
       
    33     return p;
       
    34     }
       
    35 
       
    36 //======================================================================================================
       
    37 
       
    38 void LogTestBoolExpr(TBool aRes, const TText* aFile, TInt aLine)
       
    39     {
       
    40     if(!aRes)
       
    41         {
       
    42         TPtrC fname(FileName(aFile));
       
    43         RDebug::Print(_L("*** Boolean expression evaluated to false, file: %S-%d\r\n"), &fname, aLine);
       
    44         test(EFalse, aLine);
       
    45         }
       
    46     }
       
    47 
       
    48 void LogCheck(TInt aValue, TInt aExpected, const TText* aFile, TInt aLine)
       
    49 	{
       
    50 	if(aValue != aExpected)
       
    51 		{
       
    52         TPtrC fname(FileName(aFile));
       
    53 		RDebug::Print(_L("*** Expected error: %d, got: %d, file: %S-%d\r\n"), aExpected, aValue, &fname, aLine);
       
    54 		test(EFalse, aLine);
       
    55 		}
       
    56 	}
       
    57 
       
    58 void LogCheckU(TUint aValue, TUint aExpected, const TText* aFile, TInt aLine)
       
    59 	{
       
    60 	if(aValue != aExpected)
       
    61 		{
       
    62 	    TPtrC fname(FileName(aFile));
       
    63 		RDebug::Print(_L("*** Expected error: %u, got: %u, file: %S-%d\r\n"), aExpected, aValue, &fname, aLine);
       
    64 		test(EFalse, aLine);
       
    65 		}
       
    66 	}
       
    67 
       
    68 //======================================================================================================
       
    69 
       
    70 void LogLeave(TInt aErr, const TText* aFile, const TInt aLine)
       
    71     {
       
    72     TPtrC fname(FileName(aFile));
       
    73     RDebug::Print(_L("*** LogEng test leave, err=%d, file: %S-%d\r\n"), aErr, &fname, aLine);
       
    74     User::Leave(aErr);
       
    75     }
       
    76 
       
    77 //======================================================================================================
       
    78 
       
    79 void LogPanic(const TDesC& aCategory, TInt aErr, const TText* aFile, TInt aLine)
       
    80     {
       
    81     TPtrC fname(FileName(aFile));
       
    82     RDebug::Print(_L("*** LogEng test panic'd with err=%d, category=%S, file: %S-%d\r\n"), aErr, &aCategory, &fname, aLine);
       
    83     User::Panic(aCategory, aErr);
       
    84     }
       
    85 
       
    86 //======================================================================================================
       
    87 
       
    88 #ifdef LOGGING_ENABLED
       
    89 
       
    90 void Log::New()
       
    91 	{
       
    92 	_LIT(KNewLogText, "===== NEW LOG =====");
       
    93 	//
       
    94 	RFileLogger logger;
       
    95 	TInt ret=logger.Connect();
       
    96 	if	(ret==KErrNone)
       
    97 		{
       
    98 		logger.CreateLog(KLogFolder, KLogFileName, EFileLoggingModeOverwrite);
       
    99 		logger.Write(KNewLogText);
       
   100 		}
       
   101 	logger.Close();
       
   102 	}
       
   103 
       
   104 void Log::Write(const TDesC& aText)
       
   105 	{
       
   106 	PruneLogFile();
       
   107 
       
   108 	RFileLogger logger;
       
   109 	TInt ret=logger.Connect();
       
   110 	if (ret==KErrNone)
       
   111 		{
       
   112 		logger.SetDateAndTime(EFalse,EFalse);
       
   113 		logger.CreateLog(KLogFolder, KLogFileName,EFileLoggingModeAppend);
       
   114 		TBuf<KLogEngLogBufferSize> buf;
       
   115 		TTime now;
       
   116 		now.HomeTime();
       
   117 		TDateTime dateTime;
       
   118 		dateTime = now.DateTime();
       
   119 		buf.Format(KTimeFormat,dateTime.Hour(),dateTime.Minute(),dateTime.Second(),dateTime.MicroSecond());
       
   120 		buf.AppendFormat(KTextFormat,&aText);
       
   121 
       
   122 		logger.Write(buf);
       
   123 		}
       
   124 
       
   125 	logger.Close();
       
   126 	}
       
   127 
       
   128 void Log::WriteFormat(TRefByValue<const TDesC> aFmt, ...)
       
   129 	{
       
   130 	VA_LIST list;
       
   131 	VA_START(list,aFmt);
       
   132 
       
   133 	PruneLogFile();
       
   134 
       
   135 	TBuf<2*KLogEngLogBufferSize> buf;
       
   136 	buf.SetMax();
       
   137 	buf.FillZ();
       
   138 	TTime now;
       
   139 	now.HomeTime();
       
   140 	TDateTime dateTime;
       
   141 	dateTime = now.DateTime();
       
   142 	buf.Format(KTimeFormat,dateTime.Hour(),dateTime.Minute(),dateTime.Second(),dateTime.MicroSecond());
       
   143 	buf.AppendFormatList(aFmt, list );
       
   144 
       
   145 	RFileLogger logger;
       
   146 	TInt ret=logger.Connect();
       
   147 	if (ret==KErrNone)
       
   148 		{
       
   149 		logger.SetDateAndTime(EFalse,EFalse);
       
   150 		logger.CreateLog(KLogFolder, KLogFileName,EFileLoggingModeAppend);
       
   151 		logger.Write(buf);
       
   152 		}
       
   153 
       
   154 	logger.Close();
       
   155 	}
       
   156 
       
   157 void Log::PruneLogFile()
       
   158   	{
       
   159 	const TInt KMaxLogSize = 1024 * 500;
       
   160 	_LIT(KDriveLetter, "C:\\Logs\\");
       
   161 	//
       
   162 	TFileName fileName(KDriveLetter);
       
   163 	fileName.Append(KLogFolder);
       
   164 	fileName.Append(KLogFileName);
       
   165 	//
       
   166 	RFs fsSession;
       
   167 	if	(fsSession.Connect() == KErrNone)
       
   168 		{
       
   169 		TEntry entry;
       
   170 		if	(fsSession.Entry(fileName, entry) == KErrNone)
       
   171 			{
       
   172 			// Check size and delete if its too big
       
   173 			if	(entry.iSize >= KMaxLogSize)
       
   174 				fsSession.Delete(fileName); // ignore error
       
   175 			}
       
   176 		}
       
   177 	fsSession.Close();
       
   178 	}
       
   179 
       
   180 #endif
       
   181 
       
   182 // Globals 
       
   183 GLDEF_D CTrapCleanup* theCleanup;
       
   184 GLDEF_D CActiveScheduler *testScheduler;
       
   185 GLDEF_D RFs theFs;
       
   186 GLDEF_D TFileName theLogName;
       
   187 GLDEF_D RFile theLog;
       
   188 GLDEF_D RLogTestSession theLogServ;
       
   189 
       
   190 //**********************************
       
   191 // CTestActive
       
   192 //**********************************
       
   193 
       
   194 CTestActive::CTestActive(TInt aPriority)
       
   195 :	CActive(aPriority)
       
   196 	{
       
   197 	CActiveScheduler::Add(this);
       
   198 	iDelayTime=0;
       
   199 	}
       
   200 
       
   201 CTestActive::~CTestActive()
       
   202 	{
       
   203 	Cancel();
       
   204 	}
       
   205 
       
   206 void CTestActive::DoCancel()
       
   207 	{
       
   208 	TRequestStatus* s=&iStatus;
       
   209 	User::RequestComplete(s, KErrNone);
       
   210 	}
       
   211 
       
   212 void CTestActive::StartL()
       
   213 	{
       
   214 	iDelayCompletion=EFalse;
       
   215 	iDelayTime=0;
       
   216 	iStatus = KRequestPending;
       
   217 	SetActive();
       
   218 	}
       
   219 
       
   220 void CTestActive::StartL(TInt aDelay)
       
   221 	{
       
   222 	iDelayCompletion=ETrue;
       
   223 	iDelayTime=aDelay;
       
   224 	iStatus = KRequestPending;
       
   225 	SetActive();
       
   226 	}
       
   227 
       
   228 void CTestActive::RunL() 
       
   229 	{
       
   230 	if(iDelayCompletion && iDelayTime)
       
   231 		{
       
   232 		// Wait for events in other threads to have a go....
       
   233 		User::After(iDelayTime);
       
   234 		iDelayTime=0;
       
   235 		iStoredStatus=iStatus;
       
   236 		SetActive();
       
   237 		TRequestStatus* s=&iStatus;
       
   238 		User::RequestComplete(s, KErrNone);
       
   239 		}
       
   240 	else
       
   241 		{
       
   242 		if(iDelayCompletion)
       
   243 			iStatus=iStoredStatus;
       
   244 
       
   245 		LOGTEXT("CTestActive::RunL() - Stopping the scheduler");
       
   246 		CActiveScheduler::Stop();
       
   247 		}
       
   248 	}
       
   249 
       
   250 //**********************************
       
   251 // CTestTimer
       
   252 //**********************************
       
   253 
       
   254 CTestTimer::CTestTimer()
       
   255 : CTimer(EPriorityLow)
       
   256 	{}
       
   257 
       
   258 void CTestTimer::RunL()
       
   259 	{
       
   260 	LOGTEXT("CTestTimer::RunL() - Stopping the scheduler");
       
   261 	CActiveScheduler::Stop();
       
   262 	}
       
   263 
       
   264 CTestTimer* CTestTimer::NewL()
       
   265 	{
       
   266 	CTestTimer* self = new(ELeave) CTestTimer();
       
   267 	CleanupStack::PushL(self);
       
   268 	self->ConstructL(); // CTimer
       
   269 	CActiveScheduler::Add(self);
       
   270 	CleanupStack::Pop();
       
   271 	return self;
       
   272 	}
       
   273 
       
   274 //**********************************
       
   275 // TestUtils
       
   276 //**********************************
       
   277 
       
   278 void TestUtils::Initialize(const TDesC& aName)
       
   279 	{
       
   280     test.Title();
       
   281     test.Printf(_L("%S\r\n"), &aName);
       
   282     User::RenameThread(aName);
       
   283 	}
       
   284 
       
   285 TBool TestUtils::FileExists(const TDesC& aFile)
       
   286 	{
       
   287 	TEntry entry;
       
   288 	return theFs.Entry(aFile, entry) == KErrNone;
       
   289 	}
       
   290 
       
   291 //Loads t_loghihelper process and passes for execution to t_loghihelper "aCommandLineArg" command line.
       
   292 //t_loghihelper will run, execute the command and die, returning the result of the command execution.
       
   293 //TestUtils::ExecuteRemoteL() will leave if error and return the result of the remote cmd execution to the caller.
       
   294 TInt TestUtils::ExecuteRemoteL(const TDesC& aCommandLineArg)
       
   295 	{
       
   296 	RProcess process;
       
   297 	LEAVE_IF_ERROR(process.Create(KHelperExeName, aCommandLineArg));
       
   298 	
       
   299 	TRequestStatus status;
       
   300 	process.Logon(status);
       
   301 	process.Resume();
       
   302 
       
   303 	User::WaitForRequest(status);
       
   304 	TInt exitReason = process.ExitReason();
       
   305 	
       
   306 	process.Close();
       
   307 	LEAVE_IF_ERROR(exitReason);
       
   308 
       
   309 	return exitReason;
       
   310 	}
       
   311 	
       
   312 //Runs t_loghihelper. t_loghihelper will execute the "delete LogEng database" command.
       
   313 //The "delete LogEng database" is a complex operation. The request is sent via the backup server
       
   314 //which will send a request to the LogEng server to release the LogEng database file locks and close the file.
       
   315 //After that the database will be deleted. 
       
   316 //In the same call the LogEng server will restarted and the LogEng server will re-create the database during the 
       
   317 //server startup.
       
   318 //
       
   319 //If "aCloseBeforeDelete" flag is false, then the database wil be only deleted.
       
   320 //The default value of "aCloseBeforeDelete" is true: the database will be closed, deleted and re-created.
       
   321 //But some of the LogEng tests create a CBaBackupSessionWrapper object and call CloseFileL() with the logeng
       
   322 //database name as a parameter. In this case, if another process, as t_loghicaphelper for example, attempts
       
   323 //to call CloseFileL() with the same file name as a parameter, then the caller will get KErrServerBusy error.
       
   324 //See how CBaBackupSessionWrapper::CloseFileL() is implemented on the server side.
       
   325 void TestUtils::DeleteDatabaseL(TBool aCloseBeforeDelete)
       
   326 	{
       
   327     _LIT(KCmdLine1, "-delete_db1");
       
   328     _LIT(KCmdLine2, "-delete_db2");
       
   329     (void)ExecuteRemoteL(aCloseBeforeDelete ? KCmdLine1 : KCmdLine2);
       
   330 	}
       
   331 	
       
   332 //Runs t_loghihelper. t_loghihelper will check and return whether the LogEng database is open or not.  
       
   333 TBool TestUtils::IsDatabaseOpenL()
       
   334 	{
       
   335 	_LIT(KCmdLine, "-db_is_open");
       
   336 	TInt result = ExecuteRemoteL(KCmdLine);
       
   337 	return result != 0;
       
   338 	}
       
   339 	
       
   340 //Runs t_loghihelper. t_loghihelper will add an event type to the LogEng database.  
       
   341 void TestUtils::AddEventTypeL()
       
   342 	{
       
   343 	_LIT(KCmdLine, "-add_event_type");
       
   344 	(void)ExecuteRemoteL(KCmdLine);
       
   345 	}
       
   346 	
       
   347 //Runs t_loghihelper. t_loghihelper will add an event to the LogEng database.  
       
   348 TInt TestUtils::AddEventL()
       
   349 	{
       
   350 	_LIT(KCmdLine, "-add_event");
       
   351 	return ExecuteRemoteL(KCmdLine);		
       
   352 	}
       
   353 	
       
   354 //Runs t_loghihelper. t_loghihelper will add events to the LogEng database.  
       
   355 void TestUtils::AddViewTestEventsL()
       
   356 	{
       
   357 	_LIT(KCmdLine, "-add_view_test_events");
       
   358 	(void)ExecuteRemoteL(KCmdLine);
       
   359 	}
       
   360 
       
   361 //Runs t_loghihelper. t_loghihelper will return the size of the LogEng database.  
       
   362 TInt TestUtils::DatabaseSizeL()
       
   363 	{
       
   364 	_LIT(KCmdLine, "-db_size");
       
   365 	return ExecuteRemoteL(KCmdLine);		
       
   366 	}	
       
   367 	
       
   368 //Runs t_loghihelper. t_loghihelper will replace the LogEng database with a corrupted database (for testing purposes).
       
   369 //The LogEng server will be stopped before that. The function can be used only in debug mode.
       
   370 #ifdef _DEBUG
       
   371 void TestUtils::CopyCorruptDbL()
       
   372 	{
       
   373 
       
   374 	_LIT(KCmdLine, "-copy_corrupt");
       
   375 	(void)ExecuteRemoteL(KCmdLine);
       
   376 	}
       
   377 	
       
   378 //Runs t_loghihelper. t_loghihelper will replace the LogEng database with a corrupted database (for testing purposes).
       
   379 //The LogEng server will be stopped before that. The function can be used only in debug mode.
       
   380 void  TestUtils::CopyCorruptDamagedDbL()
       
   381 	{
       
   382 
       
   383 	_LIT(KCmdLine, "-copy_corrupt_damaged");
       
   384 	(void)ExecuteRemoteL(KCmdLine);
       
   385 	}
       
   386 	
       
   387 //Runs t_loghihelper. t_loghihelper will replace the LogEng database with an old format database 
       
   388 //(no SimId column, phone number length is different). The LogEng server will be stopped before that.
       
   389 //The function can be used only in debug mode.
       
   390 void TestUtils::CopyOldDbL()
       
   391 	{
       
   392 	_LIT(KCmdLine, "-copy_old");
       
   393 	(void)ExecuteRemoteL(KCmdLine);
       
   394 	}
       
   395 #else //_DEBUG
       
   396 void TestUtils::CopyCorruptDbL()
       
   397 	{
       
   398 	RDebug::Print(_L("TestUtils::CopyCorruptDbL() has a meaningfull implementation in debug builds only.\n"));
       
   399 	}
       
   400 
       
   401 void TestUtils::CopyCorruptDamagedDbL()
       
   402 	{
       
   403 	RDebug::Print(_L("TestUtils::CopyCorruptDamagedDbL() has a meaningfull implementation in debug builds only.\n"));
       
   404 	}
       
   405 
       
   406 void TestUtils::CopyOldDbL()
       
   407 	{
       
   408 	RDebug::Print(_L("TestUtils::CopyOldDbL() has a meaningfull implementation in debug builds only.\n"));
       
   409 	}
       
   410 
       
   411 #endif//_DEBUG
       
   412 
       
   413 //Runs t_loghihelper. t_loghihelper will re-create the LogEng database and check whether LogEng client can connect to the server.   
       
   414 void TestUtils::TestInvalidSchemaL()
       
   415 	{
       
   416 	_LIT(KCmdLine, "-invalid_schema");
       
   417 	(void)ExecuteRemoteL(KCmdLine);
       
   418 	}
       
   419 
       
   420 //Runs t_loghihelper. t_loghihelper checks whether the phone number mathcing is enabled.   
       
   421 TBool TestUtils::MatchingEnabledL()
       
   422 	{
       
   423 	_LIT(KCmdLine, "-is_matching_enabled");
       
   424 	return ExecuteRemoteL(KCmdLine) != 0;
       
   425 	}
       
   426 
       
   427 //Creates HBufC object and puts it on the cleanup stack.
       
   428 //The buffer will be filled with (' ' + pos) characters, where pos is the character position in the buffer. 
       
   429 HBufC* TestUtils::CreateBufLC(TInt aLength)
       
   430 	{
       
   431 	HBufC* buf = HBufC::NewLC(aLength);
       
   432 	TPtr ptr = buf->Des();
       
   433 	for(TInt pos=0;pos<aLength;++pos)
       
   434 		{
       
   435 		ptr.Append(TChar(' ' + pos));
       
   436 		}
       
   437 	return buf;
       
   438 	}
       
   439 
       
   440 //Returns whether the two filters are equal or not.
       
   441 TBool TestUtils::FiltersEqual(const CLogFilter& aFilter1, const CLogFilter& aFilter2)
       
   442 	{
       
   443 	return aFilter1.EventType() == aFilter2.EventType() &&
       
   444 		   aFilter1.RemoteParty() == aFilter2.RemoteParty() &&
       
   445 		   aFilter1.Direction() == aFilter2.Direction() &&
       
   446 		   aFilter1.DurationType() == aFilter2.DurationType() &&
       
   447 		   aFilter1.Status() == aFilter2.Status() &&
       
   448 		   aFilter1.Contact() == aFilter2.Contact() &&
       
   449 		   aFilter1.Number() == aFilter2.Number() 
       
   450 #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM	
       
   451 		   &&
       
   452 		   aFilter1.SimId() == aFilter2.SimId()
       
   453 #endif		   
       
   454 		   ;
       
   455 	}
       
   456 
       
   457 //Creates HBufC8 object and puts it on the cleanup stack.
       
   458 //The buffer will be filled with (' ' + pos % (0xff - 32)) characters, where pos is the character position in the buffer. 
       
   459 HBufC8* TestUtils::CreateBuf8LC(TInt aLength)
       
   460 	{
       
   461 	HBufC8* buf = HBufC8::NewLC(aLength);
       
   462 	TPtr8 ptr = buf->Des();
       
   463 	for(TInt pos=0;pos<aLength;++pos)
       
   464 		{
       
   465 		ptr.Append(TChar(' ' + pos % (0xff - 32)));
       
   466 		}
       
   467 	return buf;
       
   468 	}
       
   469 
       
   470 //Returns whether the two events are equal or not.
       
   471 TBool TestUtils::EventsEqual(const CLogEvent& aEvent1, const CLogEvent& aEvent2)
       
   472 	{
       
   473 	return 	aEvent1.Id() == aEvent2.Id() &&
       
   474 			aEvent1.EventType() == aEvent2.EventType() &&
       
   475 			aEvent1.RemoteParty() == aEvent2.RemoteParty() &&
       
   476 			aEvent1.Direction() == aEvent2.Direction() &&
       
   477 			aEvent1.Time() == aEvent2.Time() &&
       
   478 			aEvent1.DurationType() == aEvent2.DurationType() &&
       
   479 			aEvent1.Duration() == aEvent2.Duration() &&
       
   480 			aEvent1.Status() == aEvent2.Status() &&
       
   481 			aEvent1.Subject() == aEvent2.Subject() &&
       
   482 			aEvent1.Number() == aEvent2.Number() &&
       
   483 			aEvent1.Contact() == aEvent2.Contact() &&
       
   484 			aEvent1.Link() == aEvent2.Link() &&
       
   485 			aEvent1.Description() == aEvent2.Description() &&
       
   486 			aEvent1.Data() == aEvent2.Data() 
       
   487 #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM	
       
   488 			&& 
       
   489 			aEvent1.SimId() == aEvent2.SimId()
       
   490 #endif			
       
   491 			; 
       
   492 	}
       
   493 
       
   494 //Returns whether the two event types are equal or not.
       
   495 TBool TestUtils::TypesEqual(const CLogEventType& aType1, const CLogEventType& aType2)
       
   496 	{
       
   497 	return	aType1.Uid() == aType2.Uid() &&
       
   498 			aType1.Description() == aType2.Description() &&
       
   499 			aType1.LoggingEnabled() == aType2.LoggingEnabled();
       
   500 	}
       
   501 
       
   502 //Waits for a key to be pressed.
       
   503 TBool TestUtils::WaitForKeyL(TTimeIntervalMicroSeconds32 aDelay, TKeyCode& aKeyCode)
       
   504 	{
       
   505 	TEST(test.Console() != NULL);
       
   506 
       
   507 	// Create timer
       
   508 	CTestTimer* timer = CTestTimer::NewL();
       
   509 	CleanupStack::PushL(timer);
       
   510 	timer->After(aDelay);
       
   511 
       
   512 	CTestActive* wait = new(ELeave)CTestActive;
       
   513 	CleanupStack::PushL(wait);
       
   514 	wait->StartL();
       
   515 
       
   516 	// Wait for key press
       
   517 	test.Console()->Read(wait->iStatus);
       
   518 	CActiveScheduler::Start();
       
   519 
       
   520 	// If timer still active a key was pressed
       
   521 	TBool keyPressed = timer->IsActive();
       
   522 
       
   523 	if (keyPressed)
       
   524 		{
       
   525 		// Get the key pressed
       
   526 		aKeyCode = test.Console()->KeyCode();
       
   527 
       
   528 		// Cancel timer
       
   529 		timer->Cancel();
       
   530 		}
       
   531 	else
       
   532 		{
       
   533 		// Cancel wait for character
       
   534 		test.Console()->ReadCancel();
       
   535 		User::WaitForRequest(wait->iStatus);
       
   536 		}
       
   537 
       
   538 	CleanupStack::PopAndDestroy(2); // wait, timer
       
   539 	return keyPressed;
       
   540 	}
       
   541 
       
   542 //Used for LogEng server side heap failure testing.
       
   543 #ifdef _DEBUG
       
   544 void TestUtils::SetLogServHeapFailureL(RHeap::TAllocFail aType, TInt aRate)
       
   545 	{
       
   546 	//this function doesn't have any effect on UREL builds 
       
   547  	//get rid of warnings in release builds
       
   548  	aType = aType;
       
   549  	aRate = aRate;
       
   550 	if (!theLogServ.Handle())
       
   551 	    LEAVE_IF_ERROR(theLogServ.Connect());
       
   552 
       
   553 	TIpcArgs  ipcArgs(aType,aRate) ;
       
   554 	LEAVE_IF_ERROR(theLogServ.Send(ELogSetHeapFail, ipcArgs));
       
   555 	}
       
   556 #else
       
   557 void TestUtils::SetLogServHeapFailureL(RHeap::TAllocFail, TInt)
       
   558 	{
       
   559 	}
       
   560 #endif//_DEBUG
       
   561 
       
   562 //**********************************
       
   563 // CLogViewChangeObserver
       
   564 //**********************************
       
   565 
       
   566 CLogViewChangeObserver* CLogViewChangeObserver::NewLC()
       
   567 	{
       
   568 	CLogViewChangeObserver* self = new(ELeave) CLogViewChangeObserver();
       
   569 	CleanupStack::PushL(self);
       
   570 	return self;
       
   571 	}
       
   572 
       
   573 CLogViewChangeObserver::~CLogViewChangeObserver()
       
   574 	{
       
   575 	Cancel();
       
   576 	delete iChanges;
       
   577 	}
       
   578 
       
   579 CLogViewChangeObserver::CLogViewChangeObserver()
       
   580 :	CActive(EPriorityStandard)
       
   581 	{
       
   582 	CActiveScheduler::Add(this);
       
   583 	}
       
   584 
       
   585 
       
   586 CLogChangeDefinition* CLogViewChangeObserver::WaitForChangesLC(TStopType aType, TInt aCount)
       
   587 	{
       
   588 	__ASSERT_ALWAYS(!iSchedulerStarted, User::Invariant());
       
   589 	Reset();
       
   590 	//
       
   591 	iExpectedChangeCount = aCount;
       
   592 	iType = aType;
       
   593 	if	(aType != EStopOnChanges)
       
   594 		SetActive();
       
   595 	//
       
   596 	iSchedulerStarted = ETrue;
       
   597 	CActiveScheduler::Start();
       
   598 	iSchedulerStarted = EFalse;
       
   599 	//
       
   600 	CLogChangeDefinition* ret = iChanges;
       
   601 	TEST(iChanges != NULL);
       
   602 	iChanges = NULL;
       
   603 	CleanupStack::PushL(ret);
       
   604 	return ret;
       
   605 	}
       
   606 
       
   607 CLogChangeDefinition* CLogViewChangeObserver::WaitForChangesLC(TCallBack aCallBack, TStopType aType, TInt aCount)
       
   608 	{
       
   609 	iHaveCallBack = ETrue;
       
   610 	iCallBack = aCallBack;
       
   611 	return WaitForChangesLC(aType, aCount);
       
   612 	}
       
   613 
       
   614 void CLogViewChangeObserver::HandleLogViewChangeEventAddedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
       
   615 	{
       
   616 	AddChangeL(ELogChangeTypeEventAdded, aId, aViewIndex);
       
   617 	if	(aChangeIndex == aTotalChangeCount-1)
       
   618 		CheckForSchedulerStop();
       
   619 	}
       
   620 
       
   621 void CLogViewChangeObserver::HandleLogViewChangeEventChangedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
       
   622 	{
       
   623 	AddChangeL(ELogChangeTypeEventChanged, aId, aViewIndex);
       
   624 	if	(aChangeIndex == aTotalChangeCount-1)
       
   625 		CheckForSchedulerStop();
       
   626 	}
       
   627 
       
   628 void CLogViewChangeObserver::HandleLogViewChangeEventDeletedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
       
   629 	{
       
   630 	AddChangeL(ELogChangeTypeEventDeleted, aId, aViewIndex);
       
   631 	if	(aChangeIndex == aTotalChangeCount-1)
       
   632 		CheckForSchedulerStop();
       
   633 	}
       
   634 
       
   635 void CLogViewChangeObserver::RunL()
       
   636 	{
       
   637 	__ASSERT_ALWAYS(iType == EStopOnRunL || iType == EStopOnBoth, User::Invariant());
       
   638 	iHaveFinishedOperation = ETrue;
       
   639 	CheckForSchedulerStop();
       
   640 	}
       
   641 
       
   642 void CLogViewChangeObserver::DoCancel()
       
   643 	{
       
   644 	TRequestStatus* s=&iStatus;
       
   645 	User::RequestComplete(s, KErrCancel);
       
   646 	}
       
   647 
       
   648 void CLogViewChangeObserver::Reset()
       
   649 	{
       
   650 	iExpectedChangeCount = 0;
       
   651 	iHaveFinishedOperation = EFalse;
       
   652 	iHaveObtainedChanges = EFalse;
       
   653 	iSchedulerStarted = EFalse;
       
   654 	iType = EStopOnChanges;
       
   655 	delete iChanges;
       
   656 	iChanges = NULL;
       
   657 	}
       
   658 
       
   659 void CLogViewChangeObserver::CheckForSchedulerStop()
       
   660 	{
       
   661 	if(iSchedulerStarted)
       
   662 		{
       
   663 		if	(iHaveCallBack)
       
   664 			{
       
   665 			iCallBack.CallBack();
       
   666 			iCallBack.iFunction = NULL;
       
   667 			iCallBack.iPtr = NULL;
       
   668 			iHaveCallBack = EFalse;
       
   669 			}
       
   670 		//
       
   671 		TBool stopScheduler = EFalse;
       
   672 		switch(iType)
       
   673 			{
       
   674 		case EStopOnChanges:
       
   675 			stopScheduler = iHaveObtainedChanges;
       
   676 			break;
       
   677 		case EStopOnRunL:
       
   678 			stopScheduler = iHaveFinishedOperation;
       
   679 			break;
       
   680 		case EStopOnBoth:
       
   681 			stopScheduler = (iHaveObtainedChanges && iHaveFinishedOperation);
       
   682 			break;
       
   683 		case EStopOnCount:
       
   684 			if	(iChanges)
       
   685 				{
       
   686 				TEST(iChanges->Count() <= iExpectedChangeCount);
       
   687 				stopScheduler = (iChanges->Count() == iExpectedChangeCount);
       
   688 				}
       
   689 		case EDontStopScheduler:
       
   690 			break;
       
   691 			}
       
   692 
       
   693 		if	(stopScheduler)
       
   694 			{
       
   695 			LOGTEXT("CLogViewChangeObserver::CheckForSchedulerStop() - Stopping the scheduler");
       
   696 			CActiveScheduler::Stop();
       
   697 			}
       
   698 		}
       
   699 	}
       
   700 
       
   701 void CLogViewChangeObserver::AddChangeL(TLogDatabaseChangeType aType, TLogId aId, TInt aViewIndex)
       
   702 	{
       
   703 	CLogChangeDefinition* changes;
       
   704 
       
   705 	if	(iChanges)
       
   706 		changes = iChanges;
       
   707 	else
       
   708 		{
       
   709 		changes = CLogChangeDefinition::NewL();
       
   710 		CleanupStack::PushL(changes);
       
   711 		}
       
   712 	//
       
   713 	changes->AddL(aId, aType, aViewIndex);
       
   714 	//
       
   715 	if	(!iChanges)
       
   716 		{
       
   717 		delete iChanges;
       
   718 		iChanges = changes;
       
   719 		CleanupStack::Pop(changes);
       
   720 		}
       
   721 	//
       
   722 	iHaveObtainedChanges = ETrue;
       
   723 	}
       
   724 
       
   725 //**********************************
       
   726 // CLogViewChangeObserverErrorTest
       
   727 //**********************************
       
   728 CLogViewChangeObserverErrorTest* CLogViewChangeObserverErrorTest::NewLC()
       
   729 	{
       
   730 	CLogViewChangeObserverErrorTest* self = new(ELeave) CLogViewChangeObserverErrorTest();
       
   731 	CleanupStack::PushL(self);
       
   732 	return self;
       
   733 	}	
       
   734 
       
   735 CLogViewChangeObserverErrorTest::CLogViewChangeObserverErrorTest()
       
   736 	{}
       
   737 	 
       
   738 void CLogViewChangeObserverErrorTest::HandleLogViewChangeEventAddedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
       
   739 	{
       
   740   	// DEF108741L - the error condition tested here is that a leave is dealt with 
       
   741   	// gracefully without any panics.
       
   742  
       
   743  	// Add a new event to the log
       
   744 	AddChangeL(ELogChangeTypeEventAdded, aId, aViewIndex);
       
   745 	if	(aChangeIndex == aTotalChangeCount-1)
       
   746 		CheckForSchedulerStop();
       
   747 	
       
   748 	// In the test case for DEF108741L this method will be effectively
       
   749 	// invoked 3 times. This code forces a leave on the middle event to 
       
   750 	// ensure that the leave is dealt with and the rest of the test 
       
   751 	// completes successfully.
       
   752 	if (aId == 1)
       
   753 		{	
       
   754 		LEAVE(KErrGeneral);
       
   755 		} 
       
   756 	}
       
   757  
       
   758 //**********************************
       
   759 // CLogSchedulerTimer
       
   760 //**********************************
       
   761 
       
   762 CLogSchedulerTimer* CLogSchedulerTimer::NewLC()
       
   763 	{
       
   764 	CLogSchedulerTimer* self = new(ELeave) CLogSchedulerTimer();
       
   765 	CleanupStack::PushL(self);
       
   766 	self->ConstructL();
       
   767 	return self;
       
   768 	}
       
   769 
       
   770 CLogSchedulerTimer::~CLogSchedulerTimer()
       
   771 	{
       
   772 	Cancel();
       
   773 	}
       
   774 
       
   775 CLogSchedulerTimer::CLogSchedulerTimer()
       
   776 :	CTimer(0)
       
   777 	{
       
   778 	CActiveScheduler::Add(this);
       
   779 	}
       
   780 
       
   781 void CLogSchedulerTimer::ConstructL()
       
   782 	{
       
   783 	CTimer::ConstructL();
       
   784 	}
       
   785 
       
   786 void CLogSchedulerTimer::Wait(TTimeIntervalMicroSeconds32 aTime)
       
   787 	{
       
   788 	After(aTime);
       
   789 	CActiveScheduler::Start();
       
   790 	}
       
   791 
       
   792 void CLogSchedulerTimer::RunL()
       
   793 	{
       
   794 	LOGTEXT("CLogSchedulerTimer::RunL() - Stopping the scheduler");
       
   795 	CActiveScheduler::Stop();
       
   796 	}
       
   797 
       
   798 
       
   799 
       
   800 
       
   801 //**********************************
       
   802 // CLogChangeNotifier
       
   803 //**********************************
       
   804 
       
   805 CLogChangeNotifier* CLogChangeNotifier::NewL()
       
   806 	{
       
   807 	CLogChangeNotifier* self = new(ELeave)CLogChangeNotifier();
       
   808 	CleanupStack::PushL(self);
       
   809 	self->ConstructL();
       
   810 	CleanupStack::Pop(self);
       
   811 	return self;
       
   812 	}
       
   813 
       
   814 CLogChangeNotifier::~CLogChangeNotifier()
       
   815 	{
       
   816 	Cancel();
       
   817 	delete iClient;
       
   818 	}
       
   819 
       
   820 CLogChangeNotifier::CLogChangeNotifier()
       
   821 : CActive(EPriorityStandard)
       
   822 	{
       
   823 	CActiveScheduler::Add(this);
       
   824 	}
       
   825 
       
   826 void CLogChangeNotifier::ConstructL()
       
   827 	{
       
   828 	iClient = CLogClient::NewL(theFs);
       
   829 
       
   830 	iStart.UniversalTime();
       
   831 	iClient->NotifyChange(10000000, iStatus);
       
   832 	SetActive();
       
   833 	}
       
   834 
       
   835 void CLogChangeNotifier::RunL()
       
   836 	{
       
   837 	TTime now;
       
   838 	now.UniversalTime();
       
   839 	TTimeIntervalSeconds seconds;
       
   840 	now.SecondsFrom(iStart, seconds);
       
   841 
       
   842 	TBuf<256> buf;
       
   843  	const TInt error = iStatus.Int();
       
   844  	if (error == KErrServerTerminated)
       
   845  		{
       
   846  		buf.Format(_L("KErrServerTerminated"));
       
   847 		User::InfoPrint(buf);
       
   848 		return;
       
   849  		}
       
   850  		
       
   851 	buf.Format(_L("%d seconds"), seconds.Int());
       
   852 	User::InfoPrint(buf);
       
   853 	
       
   854 	iStart.UniversalTime();
       
   855 	iClient->NotifyChange(10000000, iStatus);
       
   856 	SetActive();
       
   857 	}
       
   858 
       
   859 void CLogChangeNotifier::DoCancel()
       
   860 	{
       
   861 	iClient->NotifyChangeCancel();	
       
   862 	}
       
   863 
       
   864 //**********************************
       
   865 // Global
       
   866 //**********************************
       
   867 
       
   868 void SetupSchedulerL()
       
   869 	{
       
   870 	testScheduler = new (ELeave) CActiveScheduler;
       
   871 	CleanupStack::PushL( testScheduler );
       
   872 	CActiveScheduler::Install( testScheduler );
       
   873 	}
       
   874 
       
   875 void CloseScheduler()
       
   876 	{
       
   877     CleanupStack::PopAndDestroy(); // Scheduler
       
   878     testScheduler = NULL;
       
   879 	}
       
   880 
       
   881 static void CreateLogL()
       
   882     {
       
   883     LEAVE_IF_ERROR(theFs.Connect());
       
   884 
       
   885     theLogName.Copy(RProcess().FileName());
       
   886     TInt start = theLogName.LocateReverse('\\');
       
   887     TInt end = theLogName.LocateReverse('.');
       
   888     theLogName = theLogName.Mid(start + 1, end - start - 1);
       
   889 
       
   890     // create the log filename
       
   891     theLogName.Insert(0, _L("C:\\"));
       
   892 #if defined(__WINS__)
       
   893     theLogName.Append(_L(".WINS."));
       
   894 #else
       
   895     theLogName.Append(_L(".MARM."));
       
   896 #endif
       
   897 #if defined(_UNICODE)
       
   898     theLogName.Append(_L("UNICODE."));
       
   899 #else
       
   900     theLogName.Append(_L("ASCII."));
       
   901 #endif
       
   902 #if defined(_DEBUG)
       
   903     theLogName.Append(_L("DEB."));
       
   904 #else
       
   905     theLogName.Append(_L("REL."));
       
   906 #endif
       
   907     theLogName.Append(_L("LOG"));
       
   908 
       
   909     // create the logfile
       
   910     LEAVE_IF_ERROR(theLog.Replace(theFs, theLogName, EFileWrite|EFileShareExclusive));
       
   911     TBuf8<256> text;
       
   912     text.Copy(theLogName);
       
   913     theLog.Write(text);
       
   914     theLog.Write(_L8("\nTest results\n"));
       
   915     }
       
   916 
       
   917 static void CloseLog()
       
   918     {
       
   919     theLog.Write(_L8("Tests completed\n"));
       
   920     test.Printf(_L("Results saved in %S\n"), &theLogName);
       
   921     theLog.Close();
       
   922     theFs.Close();
       
   923     }
       
   924 
       
   925 void DeleteDataFile(const TDesC& aFullName)
       
   926 	{
       
   927 	RFs fsSession;
       
   928 	TInt err = fsSession.Connect();
       
   929 	if(err == KErrNone)
       
   930 		{
       
   931 		TEntry entry;
       
   932 		if(fsSession.Entry(aFullName, entry) == KErrNone)
       
   933 			{
       
   934 			RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
       
   935 			err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
       
   936 			if(err != KErrNone) 
       
   937 				{
       
   938 				RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
       
   939 				}
       
   940 			err = fsSession.Delete(aFullName);
       
   941 			if(err != KErrNone) 
       
   942 				{
       
   943 				RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
       
   944 				}
       
   945 			}
       
   946 		fsSession.Close();
       
   947 		}
       
   948 	else
       
   949 		{
       
   950 		RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
       
   951 		}
       
   952 	}
       
   953 
       
   954 static void Cleanup(void*)
       
   955 	{
       
   956 	TRAP_IGNORE(TestUtils::DeleteDatabaseL());
       
   957 	_LIT(KCntModelFileName, "c:\\system\\data\\CntModel.ini");
       
   958 	::DeleteDataFile(KCntModelFileName);
       
   959 	_LIT(KContactsFileName, "c:\\system\\data\\Contacts.cdb");
       
   960 	::DeleteDataFile(KContactsFileName);
       
   961 	::DeleteDataFile(theLogName);
       
   962 	}
       
   963 
       
   964 static void DoMainL()
       
   965 	{
       
   966 	::SetupSchedulerL();
       
   967 	TCleanupItem cleanup(&Cleanup, NULL);
       
   968 	CleanupStack::PushL(cleanup);
       
   969 	CreateLogL();
       
   970 	::doTestsL();
       
   971 	CloseLog();
       
   972     CleanupStack::PopAndDestroy();//cleanup
       
   973 	::CloseScheduler();
       
   974 	}
       
   975 
       
   976 TInt E32Main()
       
   977 	{	
       
   978 	__UHEAP_MARK;
       
   979 
       
   980 	theCleanup = CTrapCleanup::New();
       
   981     if(!theCleanup)
       
   982        {
       
   983        _LIT(KLogHiCapHelperPanic, "LogTestPanic");
       
   984         User::Panic(KLogHiCapHelperPanic, KErrNoMemory);
       
   985        }
       
   986 
       
   987 	TRAPD(err, ::DoMainL());	
       
   988 	TEST2(err, KErrNone);
       
   989 
       
   990 	delete theCleanup;	
       
   991 
       
   992 	test.Console()->SetPos(0, 13);
       
   993 
       
   994 	test.End();
       
   995 	test.Close();
       
   996 
       
   997 	__UHEAP_MARKEND;
       
   998 
       
   999 	return KErrNone;
       
  1000 	}
       
  1001 
       
  1002