sl@0: // Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: // Platform security prohibits the existing logeng tests from doing
sl@0: // direct operations on data-caged files.  Giving the tests a higher
sl@0: // capability might mask other errors.  Therefore any file manipulation
sl@0: // may be sub-contracted to this process as needed.
sl@0: // 
sl@0: //
sl@0: #include <s32file.h>
sl@0: #include <babackup.h>
sl@0: #include "t_logutil2.h"
sl@0: #include "t_logutil3.h"
sl@0: 
sl@0: const TUid KTestEventUid = {0x10005393};
sl@0: _LIT(KTestEventDesc1, "Event Type Description");
sl@0: _LIT(KTestDirection1, "Direction");
sl@0: _LIT(KTestStatus1, "Status");
sl@0: _LIT(KTestStatus2, "Changed Status");
sl@0: _LIT(KTestNumber1, "Number");
sl@0: const TLogContactItemId KTestContact1 = 0x1234;
sl@0: const TLogContactItemId KTestContact2 = 0x1234567;
sl@0: _LIT(KTestRemote1, "Remote Test 1");
sl@0: _LIT(KTestRemote2, "Remote Test 2");
sl@0: _LIT(KTestRemote3, "Remote Test 3");
sl@0: _LIT(KTestStatusT3, "Status Test 3");
sl@0: _LIT(KTestEventDesc, "Test Event");
sl@0: 
sl@0: _LIT(KLogEngPrivatePath, "c:\\private\\101f401d\\");
sl@0: 
sl@0: _LIT(KLogHiCapHelperPanic, "TLHCHlpr");
sl@0: 
sl@0: RTest TheTest(_L("t_loghicaphelper")); //used in t_logutil.cpp only
sl@0: 
sl@0: RFs theFs;
sl@0: CActiveScheduler *TheTestScheduler = NULL;
sl@0: 
sl@0: //===========================================================================================
sl@0: 
sl@0: //Supported remote operaions
sl@0: enum THelperOp
sl@0: 	{
sl@0: 	EOpNotDefined,
sl@0:     EDeleteDatabase1,
sl@0:     EDeleteDatabase2,
sl@0: 	EIsDatabaseOpen,
sl@0: 	EDatabaseSize,
sl@0: 	ECopyCorruptDbFile,
sl@0: 	ECopyCorruptDamagedDbFile,
sl@0: 	ECopyOldDbFile,
sl@0: 	EAddEvent,
sl@0: 	EAddTestEvents,
sl@0: 	EAddEventType,
sl@0: 	EInvalidSchema,
sl@0: 	EIsMatchingEnabled
sl@0: 	} ;
sl@0: 
sl@0: _LIT(KOldCorruptDatabase,"z:\\test\\corruptLogdbu.dat");
sl@0: _LIT(KOldCorruptDamagedDatabase,"z:\\test\\corruptDamagedLogdbu.dat");
sl@0: _LIT(KOldFormatDatabase,"z:\\test\\oldLogdbu.dat");
sl@0: 
sl@0: 
sl@0: CTestActive::CTestActive(TInt aPriority)
sl@0: :	CActive(aPriority)
sl@0: 	{
sl@0: 	CActiveScheduler::Add(this);
sl@0: 	iDelayTime=0;
sl@0: 	}
sl@0: 
sl@0: CTestActive::~CTestActive()
sl@0: 	{
sl@0: 	Cancel();
sl@0: 	}
sl@0: 
sl@0: void CTestActive::DoCancel()
sl@0: 	{
sl@0: 	TRequestStatus* s=&iStatus;
sl@0: 	User::RequestComplete(s, KErrNone);
sl@0: 	}
sl@0: 
sl@0: void CTestActive::StartL()
sl@0: 	{
sl@0: 	iDelayCompletion=EFalse;
sl@0: 	iDelayTime=0;
sl@0: 	iStatus = KRequestPending;
sl@0: 	SetActive();
sl@0: 	}
sl@0: 
sl@0: void CTestActive::StartL(TInt aDelay)
sl@0: 	{
sl@0: 	iDelayCompletion=ETrue;
sl@0: 	iDelayTime=aDelay;
sl@0: 	iStatus = KRequestPending;
sl@0: 	SetActive();
sl@0: 	}
sl@0: 
sl@0: void CTestActive::RunL() 
sl@0: 	{
sl@0: 	if(iDelayCompletion && iDelayTime)
sl@0: 		{
sl@0: 		// Wait for events in other threads to have a go....
sl@0: 		User::After(iDelayTime);
sl@0: 		iDelayTime=0;
sl@0: 		iStoredStatus=iStatus;
sl@0: 		SetActive();
sl@0: 		TRequestStatus* s=&iStatus;
sl@0: 		User::RequestComplete(s, KErrNone);
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		if(iDelayCompletion)
sl@0: 			iStatus=iStoredStatus;
sl@0: 
sl@0: 		LOGTEXT("CTestActive::RunL() - Stopping the scheduler");
sl@0: 		CActiveScheduler::Stop();
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: //.................................................................................................
sl@0: 
sl@0: //See TestUtils::TestInvalidSchemaL(). Re-creates the LogEng database and checkes whether a new 
sl@0: //LogEng connection can be established (by creating a CLogClient object).
sl@0: static void TestInvalidSchemaL()
sl@0: 	{
sl@0: 	TheTestScheduler = new (ELeave) CActiveScheduler;
sl@0: 	CleanupStack::PushL( TheTestScheduler );
sl@0: 	CActiveScheduler::Install( TheTestScheduler );
sl@0: 
sl@0:    	//Reseting of log engine databse is done via its backup server.  This seems a 
sl@0:    	//bit odd.  Perhaps write a CLogClient API that does it?
sl@0:    	//Create backup session wrapper
sl@0:    	CBaBackupSessionWrapper* backup = CBaBackupSessionWrapper::NewL();
sl@0:    	CleanupStack::PushL(backup);
sl@0:    
sl@0:    	//This eventually calls CLogBackup::ChangeFileLockL(..) which closes the database 
sl@0:    	//file and notifies all handles to that file that it has closed.
sl@0:    	backup->CloseFileL(KLogDatabaseName, MBackupObserver::EReleaseLockNoAccess);
sl@0:  	User::After(1000000);
sl@0:    	
sl@0:    	//Since the log engine database file is closed we can replace it.   
sl@0:    	//Once this file is deleted, the backup server notices this and attempts to reopen 
sl@0:    	//the database.  Since the file is deleted a default database is created instead.
sl@0:     RDbNamedDatabase database;
sl@0: 	TInt err = database.Replace(theFs, KLogDatabaseName);
sl@0: 	database.Close();
sl@0: 	LEAVE_IF_ERROR(err);
sl@0: 
sl@0: 	// The following will leave if there is a problem
sl@0: 	CLogClient* client = CLogClient::NewL(theFs);
sl@0: 	delete client;
sl@0: 	
sl@0: 	CleanupStack::PopAndDestroy(2); // scheduler + backup
sl@0: 	TheTestScheduler = NULL;
sl@0: 	}
sl@0: 
sl@0: //.................................................................................................
sl@0: 
sl@0: //See TestUtils::AddEventTypeL(). Adds an event type to the LogEng database.
sl@0: static void AddEventTypeL()
sl@0: 	{
sl@0: 	TheTestScheduler = new (ELeave) CActiveScheduler;
sl@0: 	CleanupStack::PushL(TheTestScheduler);
sl@0: 	CActiveScheduler::Install(TheTestScheduler);
sl@0: 
sl@0: 	CLogClient* client = CLogClient::NewL(theFs);
sl@0: 	CleanupStack::PushL(client);
sl@0: 
sl@0: 	CTestActive* active = new(ELeave)CTestActive();
sl@0: 	CleanupStack::PushL(active);
sl@0: 
sl@0: 	CLogEventType* type = CLogEventType::NewL();
sl@0: 	CleanupStack::PushL(type);
sl@0: 
sl@0: 	type->SetUid(KTestEventUid);
sl@0: 	type->SetDescription(KTestEventDesc1);
sl@0: 	type->SetLoggingEnabled(ETrue);
sl@0: 
sl@0: 	client->AddEventType(*type, active->iStatus);
sl@0: 	
sl@0: 	active->StartL();
sl@0: 	CActiveScheduler::Start();
sl@0: 	LEAVE_IF_ERROR(active->iStatus.Int());
sl@0: 	
sl@0: 	CleanupStack::PopAndDestroy(4); // scheduler, client, active, type
sl@0: 	TheTestScheduler = NULL;
sl@0: 	}
sl@0: 	
sl@0: //.................................................................................................
sl@0: 
sl@0: //See TestUtils::AddViewTestEventsL(). Adds events to the LogEng database.
sl@0: static void AddTestEventsL()
sl@0: 	{
sl@0: 	TheTestScheduler = new (ELeave) CActiveScheduler;
sl@0: 	CleanupStack::PushL(TheTestScheduler);
sl@0: 	CActiveScheduler::Install(TheTestScheduler);
sl@0: 	
sl@0: 	CTestActive* active = new(ELeave)CTestActive;
sl@0: 	CleanupStack::PushL(active);
sl@0: 
sl@0:  	CLogClient* client = CLogClient::NewL(theFs);
sl@0: 	CleanupStack::PushL(client);
sl@0: 	
sl@0: 	TLogString direction;
sl@0: 	client->GetString(direction, R_LOG_DIR_IN);
sl@0: 
sl@0: 	// Create a test event type
sl@0: 	CLogEventType* type = CLogEventType::NewL();
sl@0: 	CleanupStack::PushL(type);
sl@0: 	type->SetUid(KTestEventUid);
sl@0: 	type->SetDescription(KTestEventDesc);
sl@0: 	type->SetLoggingEnabled(ETrue);
sl@0: 
sl@0: 	// Register the event type
sl@0: 	active->StartL();
sl@0: 	client->AddEventType(*type, active->iStatus);
sl@0: 	CActiveScheduler::Start();
sl@0: 	LEAVE_IF_ERROR(active->iStatus.Int());
sl@0: 	
sl@0: 	// Now add some events...
sl@0: 	//
sl@0: 	CLogEvent* event = CLogEvent::NewL();
sl@0: 	CleanupStack::PushL(event);
sl@0: 	//
sl@0: 	event->SetEventType(KLogCallEventTypeUid);
sl@0: 	event->SetContact(KTestContact1);
sl@0: 	event->SetDirection(direction);
sl@0: 	event->SetDurationType(KLogDurationValid);
sl@0: 	event->SetNumber(KTestNumber1);
sl@0: 	event->SetRemoteParty(KTestRemote1);
sl@0: 	event->SetStatus(KTestStatus1);
sl@0: 
sl@0: 	// Add event
sl@0: 	active->StartL();
sl@0: 	client->AddEvent(*event, active->iStatus);
sl@0: 	CActiveScheduler::Start();
sl@0: 	LEAVE_IF_ERROR(active->iStatus.Int());
sl@0: 	//
sl@0: 	
sl@0: 	event->SetEventType(KTestEventUid);	// low cap visible
sl@0: 	event->SetContact(KTestContact1);
sl@0: 	event->SetDirection(direction);
sl@0: 	event->SetDurationType(KLogDurationNone);
sl@0: 	event->SetNumber(KTestNumber1);
sl@0: 	event->SetRemoteParty(KTestRemote1);
sl@0: 	event->SetStatus(KTestStatus1);
sl@0: 
sl@0: 	// Add event
sl@0: 	active->StartL();
sl@0: 	client->AddEvent(*event, active->iStatus);
sl@0: 	CActiveScheduler::Start();
sl@0: 	LEAVE_IF_ERROR(active->iStatus.Int());
sl@0: 	//
sl@0: 		
sl@0: 	event->SetEventType(KLogCallEventTypeUid);
sl@0: 	event->SetContact(KTestContact2);
sl@0: 	event->SetDirection(direction);
sl@0: 	event->SetDurationType(KLogDurationValid);
sl@0: 	event->SetNumber(KTestNumber1);
sl@0: 	event->SetRemoteParty(KTestRemote2);
sl@0: 	event->SetStatus(KTestStatus2);
sl@0: 
sl@0: 	// Add event and 4 duplicates
sl@0: 	for(TInt i=0; i<5; i++)
sl@0: 		{
sl@0: 		active->StartL();
sl@0: 		client->AddEvent(*event, active->iStatus);
sl@0: 		CActiveScheduler::Start();
sl@0: 		LEAVE_IF_ERROR(active->iStatus.Int());
sl@0: 		}
sl@0: 	
sl@0: 	event->SetEventType(KTestEventUid);	// low cap visible
sl@0: 	event->SetContact(KTestContact2);
sl@0: 	event->SetDirection(KTestDirection1);
sl@0: 	event->SetDurationType(KLogDurationData);
sl@0: 	event->SetNumber(KTestNumber1);
sl@0: 	event->SetRemoteParty(KTestRemote3);
sl@0: 	event->SetStatus(KTestStatusT3);
sl@0: 
sl@0: 	// Add event
sl@0: 	active->StartL();
sl@0: 	client->AddEvent(*event, active->iStatus);
sl@0: 	CActiveScheduler::Start();
sl@0: 	LEAVE_IF_ERROR(active->iStatus.Int());
sl@0: 	
sl@0: 	CleanupStack::PopAndDestroy(5);	// event, client, type, active, scheduler
sl@0: 	TheTestScheduler = NULL;
sl@0: 	}
sl@0: 	
sl@0: //.................................................................................................
sl@0: 
sl@0: //See TestUtils::AddEventL(). Adds an event to the LogEng database.
sl@0: //The event type is set to be: KLogCallEventTypeUid.
sl@0: //Return: the Id of the added event
sl@0: static TInt AddEventL()
sl@0: 	{
sl@0: 	TheTestScheduler = new (ELeave) CActiveScheduler;
sl@0: 	CleanupStack::PushL(TheTestScheduler);
sl@0: 	CActiveScheduler::Install(TheTestScheduler);
sl@0: 
sl@0: 	CLogClient* client = CLogClient::NewL(theFs);
sl@0: 	CleanupStack::PushL(client);
sl@0: 
sl@0: 	CTestActive* active = new(ELeave)CTestActive();
sl@0: 	CleanupStack::PushL(active);
sl@0: 
sl@0: 	CLogEvent* event = CLogEvent::NewL();
sl@0: 	CleanupStack::PushL(event);
sl@0: 	
sl@0: 	event->SetEventType(KLogCallEventTypeUid);
sl@0: 
sl@0: 	active->StartL();
sl@0: 	client->AddEvent(*event, active->iStatus);
sl@0: 	CActiveScheduler::Start();
sl@0: 	LEAVE_IF_ERROR(active->iStatus.Int());
sl@0:     TLogId eventId = event->Id();
sl@0: 	
sl@0: 	CleanupStack::PopAndDestroy(4); // scheduler, client, active, event
sl@0: 	TheTestScheduler = NULL;
sl@0: 	return eventId;
sl@0: 	}
sl@0: 
sl@0: //.................................................................................................
sl@0: 
sl@0: #ifdef _DEBUG
sl@0: static void StopLogServerL()
sl@0: 	{
sl@0: 	static RLogTestSession logServSession;
sl@0: 	//this function doesn't have any effect on UREL builds as LogEng server doesn't 
sl@0: 	//support the transient mode in UREL builds	
sl@0: 	//Used for LogEng server side heap failure testing.
sl@0: 	TInt error = KErrNone;
sl@0: 	  
sl@0: 	if(!logServSession.Handle())
sl@0: 		{
sl@0: 		error = logServSession.Connect();
sl@0: 		}
sl@0: 	  
sl@0: 	// Is the server running?
sl@0: 	if(error == KErrNotFound)
sl@0: 		{
sl@0: 		return;
sl@0: 		}
sl@0: 	LEAVE_IF_ERROR(error);
sl@0: 	  
sl@0: 	// Make the server transient
sl@0: 	TInt p0 = 1;
sl@0: 	TIpcArgs  ipcArgs(p0);
sl@0: 	LEAVE_IF_ERROR(logServSession.Send(ELogMakeTransient, ipcArgs));
sl@0: 	  
sl@0: 	logServSession.Close();
sl@0: 	  
sl@0: 	User::After(6 * 1000000); // Enough time for the server to exit
sl@0: 	}
sl@0: #else//_DEBUG
sl@0: static void StopLogServerL()
sl@0: 	{
sl@0: 	RDebug::Print(_L("StopLogServerL(): the LogEng server cannot be stopped in release mode. ELogMakeTransient is a debug message.\n"));
sl@0: 	}
sl@0: #endif//_DEBUG
sl@0: 
sl@0: //.................................................................................................
sl@0: 
sl@0: static void DoDeleteDatabaseL(const TDesC& aDbPath, TBool aCloseBeforeDelete)
sl@0:     {
sl@0:     CBaBackupSessionWrapper* backup = NULL;
sl@0:     if(aCloseBeforeDelete)
sl@0:         {
sl@0:         //Reseting of log engine databse is done via its backup server.
sl@0:         //Create backup session wrapper
sl@0:         backup = CBaBackupSessionWrapper::NewL();
sl@0:         CleanupStack::PushL(backup);
sl@0: 
sl@0:         //This eventually calls CLogBackup::ChangeFileLockL(..) which closes the database 
sl@0:         //file and notifies all handles to that file that it has closed.
sl@0:         backup->CloseFileL(aDbPath, MBackupObserver::EReleaseLockNoAccess);
sl@0:         User::After(1000000);
sl@0:         }
sl@0: 
sl@0:     //Since the log engine database file is closed we can delete it.   
sl@0:     //Once this file is deleted, the backup server notices this and attempts to reopen 
sl@0:     //the database.  Since the file is deleted a default database is created instead.
sl@0:     
sl@0:     TInt error = theFs.Delete(aDbPath);
sl@0: 
sl@0:     if(!(error == KErrNone || error == KErrNotFound || error == KErrPathNotFound) )
sl@0:         {
sl@0:         RDebug::Print(_L("DoDeleteDatabaseL(), Error %d deleting database \"%S\"\n"),error, &aDbPath);
sl@0:         }
sl@0:     else
sl@0:         {
sl@0:         RDebug::Print(_L("DoDeleteDatabaseL(), Database \"%S\" deleted ok\n"), &aDbPath);
sl@0:         }
sl@0: 
sl@0:     if(aCloseBeforeDelete)
sl@0:         {
sl@0:         //The next line restarts the logeng server and re-creates logdbu.dat file.
sl@0:         CleanupStack::PopAndDestroy(backup);
sl@0:             
sl@0:         TInt count = 10;
sl@0:         while(count--)
sl@0:             {
sl@0:             User::After(100000);
sl@0:             TEntry entry;
sl@0:             if(theFs.Entry(aDbPath, entry) == KErrNone)
sl@0:                 {
sl@0:                 break;
sl@0:                 }
sl@0:             }
sl@0:         }
sl@0:     }
sl@0: 
sl@0: //See TestUtils::DeleteDatabaseL().
sl@0: //If "aCloseBeforeDelete" is true then re-create the LogEng database.
sl@0: static void DeleteDatabaseL(TBool aCloseBeforeDelete)
sl@0:     {
sl@0:     RDebug::Print(_L("DeleteDatabaseL(), Deleting database \"%S\"\r\n"), &KLogDatabaseName);
sl@0: 
sl@0:     TRAPD(err, DoDeleteDatabaseL(KLogDatabaseName, aCloseBeforeDelete));
sl@0:     if(err == KErrNotFound || err == KErrPathNotFound)
sl@0:         {
sl@0:         err = KErrNone;
sl@0:         }
sl@0:     LEAVE_IF_ERROR(err);
sl@0:     }
sl@0: 
sl@0: //.................................................................................................
sl@0: 
sl@0: //See TestUtils::CopyCorruptDbL().
sl@0: //See TestUtils::CopyOldDbL(). 
sl@0: //See TestUtils::CopyCorruptDamagedDbL()
sl@0: //
sl@0: //The LogEng database will be replaced with a the database which name is passed as a parameter (for testing purposes).
sl@0: //The LogEng server will be stopped.
sl@0: //This call works only in debug mode.
sl@0: static void CopyDatabaseL(const TDesC& aNewDatabase)
sl@0: 	{
sl@0: 	StopLogServerL();
sl@0: 	
sl@0: 	CFileMan* fileMan=CFileMan::NewL(theFs);
sl@0: 	CleanupStack::PushL(fileMan);
sl@0: 	
sl@0: 	DeleteDatabaseL(ETrue); // it won't be replaced as the server has stopped
sl@0: 
sl@0:   	TInt err = fileMan->Copy(aNewDatabase, KLogDatabaseName);
sl@0: 	if(err != KErrNone)
sl@0: 		{
sl@0: 		// Note this only works on textshell ROMs, techview ROMs fail here with KErrInUse (-14)
sl@0: 		RDebug::Print(_L("CopyDatabaseL(), File copy \"%S\" to \"%S\", err=%d\n"), &aNewDatabase, &KLogDatabaseName, err);
sl@0: 		LEAVE(err);
sl@0: 		}
sl@0: 	// files copied are sometimes read-only, so make read-write	
sl@0: 	err = theFs.SetAtt(KLogDatabaseName, 0, KEntryAttReadOnly);
sl@0: 	if(err != KErrNone)
sl@0: 		{
sl@0: 		RDebug::Print(_L("CopyDatabaseL(), Set \"%S\" file attributes err=%d\n"), &KLogDatabaseName, err);
sl@0: 		LEAVE(err);
sl@0: 		}
sl@0: 
sl@0: 	CleanupStack::PopAndDestroy(); // fileMan
sl@0: 	}
sl@0: 
sl@0: //.................................................................................................
sl@0: 
sl@0: //See TestUtils::DatabaseSizeL().
sl@0: //Returns the LogEng database size.
sl@0: static TInt DatabaseSizeL()
sl@0: 	{
sl@0: 	TEntry file;
sl@0: 	LEAVE_IF_ERROR(theFs.Entry(KLogDatabaseName, file));
sl@0: 	return file.iSize;
sl@0: 	}
sl@0: 
sl@0: //.................................................................................................
sl@0: 
sl@0: static void Initialize(const TDesC& aName)
sl@0: 	{
sl@0:     User::RenameThread(aName);
sl@0: 	}
sl@0: 
sl@0: //.................................................................................................
sl@0: 
sl@0: //See TestUtils::IsDatabaseOpenL().
sl@0: //Returns whether the LogEng database is open or not.
sl@0: static TBool DatabaseIsOpenL()
sl@0: 	{
sl@0: 	TBool answer;
sl@0: 	LEAVE_IF_ERROR(theFs.IsFileOpen(KLogDatabaseName, answer));
sl@0: 	return answer;
sl@0: 	}
sl@0: 
sl@0: //.................................................................................................
sl@0: 
sl@0: //See TestUtils::MatchingEnabledL().
sl@0: //The function opens the LogEng repository (KUidLogengRepository) and gets the value of 
sl@0: //KContactMatchCountRepKey resource.
sl@0: //If the value is 0 - "contacts matching" part of the test will be skipped.
sl@0: static TBool MatchingEnabledL()
sl@0: 	{
sl@0: 	TInt contactMatchCount = 0;
sl@0: 	TLogContactNameFormat contactNameFormat = ELogWesternFormat; 
sl@0: 	LogGetContactmatchCountAndNameFormatL(contactMatchCount, contactNameFormat);
sl@0:     RDebug::Print(_L("** contact match count = %d, contact name format = %d\r\n"), contactMatchCount, (TInt)contactNameFormat);
sl@0: 	return contactMatchCount > 0;
sl@0: 	}
sl@0: 
sl@0: //.................................................................................................
sl@0: 
sl@0: static TInt DoTaskL(THelperOp aOperation)
sl@0:     {
sl@0:     TInt rc = KErrNone;
sl@0: 	switch(aOperation)
sl@0: 	    {
sl@0:         case EDeleteDatabase1:
sl@0:             DeleteDatabaseL(ETrue);
sl@0:             break;
sl@0:         case EDeleteDatabase2:
sl@0:             DeleteDatabaseL(EFalse);
sl@0:             break;
sl@0:         case EIsDatabaseOpen:
sl@0:             rc = DatabaseIsOpenL();
sl@0:             break;
sl@0:         case EDatabaseSize:
sl@0:             rc = DatabaseSizeL();
sl@0:             break;
sl@0:         case ECopyCorruptDbFile:
sl@0:             CopyDatabaseL(KOldCorruptDatabase);
sl@0:             break;
sl@0:         case ECopyCorruptDamagedDbFile:
sl@0:             CopyDatabaseL(KOldCorruptDamagedDatabase);
sl@0:             break;
sl@0:         case ECopyOldDbFile:
sl@0:             CopyDatabaseL(KOldFormatDatabase);
sl@0:             break;
sl@0:         case EAddEvent:
sl@0:             rc = AddEventL();
sl@0:             break;
sl@0:         case EAddTestEvents:
sl@0:             AddTestEventsL();
sl@0:             break;
sl@0:         case EAddEventType:
sl@0:             AddEventTypeL();
sl@0:             break;
sl@0:         case EInvalidSchema:
sl@0:             TestInvalidSchemaL();
sl@0:             break;
sl@0:         case EIsMatchingEnabled:
sl@0:             rc = MatchingEnabledL();
sl@0:             break;
sl@0:         default:
sl@0:             rc = KErrNone;	// go away quietly
sl@0:             break;
sl@0: 	    }
sl@0: 	LEAVE_IF_ERROR(rc);
sl@0: 	return rc;
sl@0:     }
sl@0: 
sl@0: //.................................................................................................
sl@0: 
sl@0: static THelperOp TaskType(const TDesC& aCmdLine)
sl@0:     {
sl@0:     THelperOp task = EOpNotDefined;
sl@0:     
sl@0:     if(aCmdLine.CompareF(_L("-delete_db1")) == 0)
sl@0:         {
sl@0:         task = EDeleteDatabase1;
sl@0:         }
sl@0:     else if(aCmdLine.CompareF(_L("-delete_db2")) == 0)
sl@0:         {
sl@0:         task = EDeleteDatabase2;
sl@0:         }
sl@0:     else if(aCmdLine.CompareF(_L("-db_is_open")) == 0)
sl@0:         {
sl@0:         task = EIsDatabaseOpen;
sl@0:         }
sl@0:     else if(aCmdLine.CompareF(_L("-db_size")) == 0)
sl@0:         {
sl@0:         task = EDatabaseSize;
sl@0:         }
sl@0:     else if(aCmdLine.CompareF(_L("-copy_corrupt")) == 0)
sl@0:         {
sl@0:         task = ECopyCorruptDbFile;
sl@0:         }
sl@0:     else if(aCmdLine.CompareF(_L("-copy_corrupt_damaged")) == 0)
sl@0:         {
sl@0:         task = ECopyCorruptDamagedDbFile;
sl@0:         }
sl@0:     else if(aCmdLine.CompareF(_L("-copy_old")) == 0)
sl@0:         {
sl@0:         task = ECopyOldDbFile;
sl@0:         }
sl@0:     else if(aCmdLine.CompareF(_L("-add_event")) == 0)
sl@0:         {
sl@0:         task = EAddEvent;
sl@0:         }
sl@0:     else if(aCmdLine.CompareF(_L("-add_view_test_events")) == 0)
sl@0:         {
sl@0:         task = EAddTestEvents;
sl@0:         }
sl@0:     else if(aCmdLine.CompareF(_L("-add_event_type")) == 0)   
sl@0:         {
sl@0:         task = EAddEventType;
sl@0:         }
sl@0:     else if(aCmdLine.CompareF(_L("-invalid_schema")) == 0)
sl@0:         {
sl@0:         task = EInvalidSchema;
sl@0:         }
sl@0:     else if(aCmdLine.CompareF(_L("-is_matching_enabled")) == 0)
sl@0:         {
sl@0:         task = EIsMatchingEnabled;
sl@0:         }
sl@0:     else
sl@0:         {
sl@0:         RDebug::Print(_L("** t_logHiCapHelper, ** Bad command line argument: %S\r\n"), &aCmdLine);
sl@0:         User::Panic(KLogHiCapHelperPanic, KErrArgument);
sl@0:         }
sl@0:     return task;
sl@0:     }
sl@0: 
sl@0: static TInt EnvCreate()
sl@0:     {
sl@0:     TInt err = theFs.Connect();
sl@0:     if(err == KErrNone)
sl@0:         {
sl@0:         err = theFs.MkDirAll(KLogEngPrivatePath);
sl@0:         if(err == KErrAlreadyExists)
sl@0:             {
sl@0:             err = KErrNone; 
sl@0:             }
sl@0:         }
sl@0:     if(err != KErrNone)
sl@0:         {
sl@0:         RDebug::Print(_L("** t_logHiCapHelper, error %d creating test environment\r\n"), err);
sl@0:         }
sl@0:     return err;
sl@0:     }
sl@0: 
sl@0: TInt E32Main()
sl@0: 	{	
sl@0: 	__UHEAP_MARK;
sl@0: 	
sl@0: 	Initialize(_L("t_loghicaphelper"));
sl@0: 
sl@0: 	CTrapCleanup* tc = CTrapCleanup::New();
sl@0: 	if(!tc)
sl@0: 	   {
sl@0:         User::Panic(KLogHiCapHelperPanic, KErrNoMemory);
sl@0: 	   }
sl@0: 	
sl@0: 	TBuf<64> cmdLine;
sl@0: 	User::CommandLine(cmdLine);
sl@0: 	THelperOp task = TaskType(cmdLine);
sl@0: 
sl@0:     TInt rc = 0;
sl@0: 	TInt err = EnvCreate();
sl@0: 	if(err == KErrNone)
sl@0: 	    {
sl@0: 	    TRAP(err, rc = DoTaskL(task));    
sl@0: 	    if(err < 0)
sl@0: 	        {
sl@0: 	        rc = err;
sl@0: 	        RDebug::Print(_L("** t_logHiCapHelper, DoTaskL(), Task %d, Error %d\n"), task, rc);
sl@0: 	        }
sl@0: 	    }
sl@0: 
sl@0:     theFs.Close();
sl@0: 	delete tc;
sl@0: 	
sl@0: 	__UHEAP_MARKEND;
sl@0: 
sl@0: 	return rc;
sl@0: 	}
sl@0: