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