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