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