--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/searcher/tsrc/robustnesstest/src/crobustnesstest.cpp Mon Apr 19 14:40:16 2010 +0300
@@ -0,0 +1,457 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "CRobustnessTest.h"
+#include "SearchServerCommon.h"
+#include "CStressWorker.h"
+#include "CLog.h"
+#include "RSearchServerSession.h"
+
+#include "SearchServerTesting.h"
+
+_LIT( KLogFile, "c:\\Data\\robustness\\log.txt" );
+_LIT( KRecordFile, "c:\\Data\\robustness\\record.csv" );
+_LIT( KTempRecordFile, "c:\\Data\\robustness\\_record.csv" );
+//_LIT( KReportFile, "c:\\Data\\robustness\\report.txt" );
+_LIT( KConfigFile, "c:\\Data\\robustness\\config.txt" );
+
+CRobustnessTest::CRobustnessTest( CConsoleBase& aConsole,
+ MRobustnessTestObserver& aObserver )
+: iConsole( aConsole ),
+ iOwnedLog( 0 ),
+ iObserver( aObserver ),
+ iPeriodic( 0 ),
+ iSearchServerMonitor( 0 ),
+ iStressWorker( 0 ),
+ iTick( 0 )
+ {
+ }
+
+void CRobustnessTest::ConstructL( )
+ {
+ User::LeaveIfError( iFs.Connect() );
+ ConfigureL();
+
+ iSearchServerMonitor =
+ new ( ELeave ) CProcessMonitor();
+ iStressWorker = new ( ELeave ) CStressWorker( iLog,
+ iPreIndex,
+ iIndexAverageItems,
+ iIndexingEnabled,
+ iDeletesEnabled,
+ iSearchersEnabled,
+ iCancellingEnabled,
+ iIndexerSleep,
+ iSearcherSleep );
+
+ iPeriodic = CPeriodic::NewL( EPriorityNormal );
+ }
+
+TInt CRobustnessTest::ReadNumberL( TPtrC8& left )
+ {
+ while ( ETrue )
+ {
+ // Try to find end of line
+ TInt eol = left.Find( _L8( "\n" ) );
+ if ( eol < 0 ) User::Leave( KErrNotFound );
+
+ TPtrC8 line = left.Left( eol );
+ left.Set( left.Mid(eol+1) );
+
+ TLex8 lex;
+ lex.Assign( line );
+ lex.SkipSpace();
+ if ( !lex.Eos() && lex.Peek() != '#' )
+ {
+ TInt ret;
+ lex.Val( ret );
+ return ret;
+ }
+ }
+ }
+
+void CRobustnessTest::ConfigureL()
+ {
+ iTickCount = 15;
+ iTickLengthSeconds = 60; // 1 minute
+ iPreIndex = 0;
+ iIndexAverageItems = 1000;
+ iIndexingEnabled = ETrue;
+ iDeletesEnabled = ETrue;
+ iSearchersEnabled = ETrue;
+ iCancellingEnabled = ETrue;
+ iIndexerSleep = 100;
+ iSearcherSleep = 20;
+
+ RFile file;
+ if ( file.Open( iFs, KConfigFile, EFileRead ) == KErrNone )
+ {
+ CleanupClosePushL( file );
+
+ TInt size;
+ file.Size( size );
+
+ HBufC8* config = HBufC8::NewLC( size );
+ TPtr8 des( config->Des() );
+ User::LeaveIfError( file.Read( 0, des, size ) );
+
+ TPtrC8 loc = *config;
+
+ iTickCount = ReadNumberL( loc );
+ iTickLengthSeconds = ReadNumberL( loc );
+ iPreIndex = ReadNumberL( loc );
+ iIndexAverageItems = ReadNumberL( loc );
+ iIndexingEnabled = ReadNumberL( loc );
+ iDeletesEnabled = ReadNumberL( loc );
+ iSearchersEnabled = ReadNumberL( loc );
+ iCancellingEnabled = ReadNumberL( loc );
+ iIndexerSleep = ReadNumberL( loc );
+ iSearcherSleep = ReadNumberL( loc );
+
+ CleanupStack::PopAndDestroy( config );
+ CleanupStack::PopAndDestroy(); // file;
+ }
+ }
+
+
+void CRobustnessTest::StartL()
+ {
+ //
+ // Step 0: Start logging
+ iOwnedLog = CFileConsoleLog::NewL( &iConsole, KLogFile );
+ iLog.SetLog( *iOwnedLog );
+
+ //
+ // Step 1. Fire up the search server
+ RSearchServerSession session;
+ User::LeaveIfError( session.Connect() );
+ session.Close();
+
+ //
+ // Step 2. Start monitoring the search server
+ iSearchServerMonitor->StartL( *this, KSearchServerName );
+
+ //
+ // Step 3. Clear old log and request search server to record RAM usage
+ iFs.Delete( KServerRecordFile ); // ignore errors
+ iFs.Delete( KRecordFile ); // ignore errors
+ iFs.Delete( KTempRecordFile ); // ignore errors
+ AddStatsLabelsL(); // prepare our own statistics record
+
+ RFile file;
+ iFs.MkDirAll( KStartRecordingSignalFile );
+ User::LeaveIfError( file.Create( iFs, KStartRecordingSignalFile, EFileWrite ) );
+ file.Close();
+
+ //
+ // Step 4. Start stressing the search searver
+ iStressWorker->StartL();
+
+ //
+ // Step 5. Set up the clock for checking reports and ending experiment
+ TTimeIntervalMicroSeconds32 tickInterval( 1000*1000*iTickLengthSeconds );
+ iPeriodic->Start( tickInterval,
+ tickInterval,
+ TCallBack( CRobustnessTest::CallTick, this ) );
+
+ //
+ // We are done
+ iLog.LogL( _L( "started" ) );
+ }
+
+CRobustnessTest::~CRobustnessTest()
+ {
+ iFs.Close();
+
+ if ( iPeriodic )
+ {
+ iPeriodic->Cancel();
+ delete iPeriodic;
+ }
+ if ( iSearchServerMonitor )
+ {
+ iSearchServerMonitor->Cancel();
+ delete iSearchServerMonitor;
+ }
+ if ( iStressWorker )
+ {
+ if ( iStressWorker->IsActive() ) iStressWorker->Finish();
+ delete iStressWorker;
+ }
+ delete iOwnedLog;
+ }
+
+namespace
+ {
+ TPtrC8 ReadLineL( TPtrC8& loc )
+ {
+ TInt linefeed = loc.Find( _L8("\n") );
+ if ( linefeed < 0 )
+ {
+ return loc.Right( 0 );
+ }
+
+ TPtrC8 ret( loc.Left( linefeed ) );
+ loc.Set( loc.Mid( linefeed + 1 ) );
+ return ret;
+ }
+ }
+
+
+void CRobustnessTest::FinalizeRecordsL()
+ {
+ // Simply merge line by line
+ RFile test;
+ User::LeaveIfError( test.Open( iFs, KTempRecordFile, EFileRead ) );
+ CleanupClosePushL( test );
+
+ RFile server;
+ User::LeaveIfError( server.Open( iFs, KServerRecordFile, EFileRead ) );
+ CleanupClosePushL( server );
+
+ RFile target;
+ User::LeaveIfError( target.Create( iFs, KRecordFile, EFileWrite ) );
+ CleanupClosePushL( target );
+
+ HBufC8* testBuf = HBufC8::NewLC( 2048 );
+ HBufC8* serverBuf = HBufC8::NewLC( 2048 );
+
+ TPtr8 testBufDes = testBuf->Des();
+ test.Read( testBufDes );
+ TPtr8 serverBufDes = serverBuf->Des();
+ server.Read( serverBufDes );
+
+ TPtrC8 testLoc = *testBuf;
+ TPtrC8 serverLoc = *serverBuf;
+
+ for ( TInt i = 0; i < iTick; i++ )
+ {
+ TPtrC8 testLine = ReadLineL( testLoc );
+ TPtrC8 serverLine = ReadLineL( serverLoc );
+
+ target.Write( testLine );
+ target.Write( serverLine );
+ target.Write( _L8( "\n" ) );
+ }
+
+ target.Flush();
+
+ CleanupStack::PopAndDestroy( serverBuf );
+ CleanupStack::PopAndDestroy( testBuf );
+
+ CleanupStack::PopAndDestroy( 3 ); // target, server, test
+ }
+
+
+void CRobustnessTest::AppendRecordL( RPointerArray<HBufC8>& aStats )
+ {
+ RFile file;
+ TInt err = file.Open( iFs, KTempRecordFile, EFileWrite );
+ if ( err == KErrNotFound )
+ {
+ err = file.Create( iFs, KTempRecordFile, EFileWrite );
+ }
+ User::LeaveIfError( err );
+ CleanupClosePushL( file );
+
+ TInt end = 0;
+ file.Seek( ESeekEnd, end );
+
+ TInt defaultWidth = 8;
+
+ for ( TInt i = 0; i < aStats.Count(); i++ )
+ {
+ file.Write( *aStats[i] );
+ TInt spaces = Max( 0, defaultWidth - aStats[i]->Length() );
+ for ( TInt j = 0; j < spaces; j++ )
+ {
+ file.Write( _L8( " " ) );
+ }
+ file.Write( _L8( "; " ) );
+ }
+ file.Write( _L8( "\n" ) );
+
+ file.Flush();
+ CleanupStack::PopAndDestroy(); // file
+ }
+
+void CRobustnessTest::AddStatsLabelsL()
+ {
+ RPointerArray<HBufC8> stats;
+
+ TRAPD( err, stats.Append( _L8( "tick" ).AllocL() ) );
+
+ if ( err == KErrNone )
+ TRAP( err, iStressWorker->AppendStatsLabelsL( stats ) );
+
+ if ( err == KErrNone )
+ TRAP( err, AppendRecordL( stats ) );
+
+ if ( err != KErrNone )
+ iLog.LogL( _L( "adding labels failed") );
+
+ stats.ResetAndDestroy();
+ stats.Close();
+ }
+
+void CRobustnessTest::AddStatsEntryL()
+ {
+ RPointerArray<HBufC8> stats;
+
+ TRAPD( err,
+ HBufC8* buf = HBufC8::NewL( 32 );
+ buf->Des().AppendNum( iTick );
+ stats.Append( buf )
+ );
+
+ if ( err == KErrNone )
+ TRAP( err, iStressWorker->AppendStatsL( stats ) );
+
+ if ( err == KErrNone )
+ TRAP( err, AppendRecordL( stats ) );
+
+ if ( err != KErrNone )
+ iLog.LogL( _L( "adding stats failed") );
+
+ stats.ResetAndDestroy();
+ stats.Close();
+ }
+
+void CRobustnessTest::Tick()
+ {
+ if ( iTick++ < iTickCount )
+ {
+ TRAP_IGNORE( iLog.LogL( _L( "tick") ) );
+
+ TInt err;
+ //
+ // Request server to dump performance record
+ TRAP( err, AddStatsEntryL() );
+ if ( err != KErrNone )
+ {
+ TRAP_IGNORE( iLog.LogL( _L( "adding record failed" ) ) );
+ }
+
+ RFile file;
+ err = file.Create( iFs, KDumpRecordSignalFile, EFileWrite );
+ if ( err == KErrNone )
+ {
+ file.Close();
+ }
+ else
+ {
+ TRAP_IGNORE( iLog.LogL( _L( "requesting server record failed" ) ) );
+ }
+
+ TRAP( err, iStressWorker->ReportL() );
+ if ( err != KErrNone )
+ {
+ TRAP_IGNORE( iLog.LogL( _L( "adding record failed" ) ) );
+ }
+ }
+ else
+ {
+ TRAPD( err,
+ iPeriodic->Cancel();
+ iLog.LogL( _L( "shutting down" ) );
+ User::LeaveIfError( iStressWorker->Finish() );
+ User::LeaveIfError( iFs.Connect() );
+ RFile file;
+ User::LeaveIfError( file.Create( iFs, KDumpRecordSignalFile, EFileWrite ) );
+ file.Close();
+ User::LeaveIfError( file.Create( iFs, KStopRecordingSignalFile, EFileWrite ) );
+ file.Close();
+ User::LeaveIfError( file.Create( iFs, KShutdownSignalFile, EFileWrite ) );
+ file.Close();
+ );
+ if ( err != KErrNone )
+ {
+ TRAP_IGNORE( iLog.LogL( _L( "failed with %d" ), err ) );
+
+ TRAP_IGNORE( FinishL() );
+ }
+ }
+ }
+
+TInt CRobustnessTest::CallTick(TAny* aThis)
+ {
+ reinterpret_cast<CRobustnessTest*>(aThis)->Tick();
+ return KErrNone;
+ }
+
+void CRobustnessTest::FinishL()
+ {
+ if ( iPeriodic ) iPeriodic->Cancel();
+ if ( iStressWorker ) iStressWorker->Finish();
+ if ( iSearchServerMonitor ) iSearchServerMonitor->Cancel();
+
+ TRAPD(err,
+ // Create a brand new record file by merging the server record
+ // with the robustness test record
+ iFs.Delete( KRecordFile );
+ FinalizeRecordsL();
+ iFs.Delete( KTempRecordFile );
+ );
+ if ( err != KErrNone )
+ TRAP_IGNORE( iLog.LogL( _L( "finalizing record failed (%d)" ), err ); );
+
+ if ( iTick == ( iTickCount+1 ) )
+ {
+ TRAP_IGNORE( iLog.LogL( _L( "finished") ) );
+ }
+ else
+ {
+ TRAP_IGNORE( iLog.LogL( _L( "interrupted by server termination") ) );
+ TRAP_IGNORE( iLog.LogL( _L( "failed") ) );
+ }
+
+
+ iObserver.FinishedL( *this );
+ }
+
+void CRobustnessTest::ProcessFinished( CProcessMonitor& aMonitor,
+ TExitType aExitType ,
+ TExitCategoryName aCategory,
+ TInt aExitReason )
+ {
+ switch ( aExitType )
+ {
+ case EExitKill:
+ iLog.LogL( _L( "%S shut down." ), &aMonitor.ProcessName() );
+ break;
+ case EExitTerminate:
+ iLog.LogL( _L( "%S terminated." ), &aMonitor.ProcessName() );
+ break;
+ case EExitPanic:
+ iLog.LogL( _L( "%S paniced %S %d." ),
+ &aMonitor.ProcessName(),
+ &aCategory,
+ aExitReason );
+ break;
+ }
+ FinishL();
+ }
+
+void CRobustnessTest::Failed( CProcessMonitor& aMonitor,
+ TInt aError )
+ {
+ iLog.LogL( _L( "Monitoring %S failed with %d." ),
+ &aMonitor.ProcessName(),
+ aError );
+ FinishL();
+ }
+