diff -r 86a2e675b80a -r 813b186005b6 stif/TestServer/src/TestServer.cpp --- a/stif/TestServer/src/TestServer.cpp Mon Jun 28 15:36:07 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,976 +0,0 @@ -/* -* Copyright (c) 2009 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: This module contains implementation of CTestServer -* class member functions. -* -*/ - -// INCLUDE FILES -#include -#include -#include "TestEngineClient.h" -#include -#include -#include "TestServer.h" -#include "TestServerCommon.h" -#include - -// EXTERNAL DATA STRUCTURES - -// EXTERNAL FUNCTION PROTOTYPES - -// CONSTANTS - -// MACROS - -// LOCAL CONSTANTS AND MACROS - -// MODULE DATA STRUCTURES - -// Struct to pass parameters to server thread -struct TThreadStartTestServer - { - TFileName iName; // Server name - RThread iServerThread; // The server thread - RSemaphore iStarted; // Startup syncronisation semaphore - TBool iInNewThread; // Is thread running in new process? - TInt iStartupResult;// Start-up result - TBool iUiTesting; // Is it testserver for UI testing - CTestThreadContainerRunnerFactory* iTestThreadContainerRunnerFactory; // Pointer to CTestThreadContainerRunner. Defined when - // iUiTesting is true - }; - -// LOCAL FUNCTION PROTOTYPES - -// FORWARD DECLARATIONS - -// ==================== LOCAL FUNCTIONS ======================================= - -// None - -// ================= MEMBER FUNCTIONS ========================================= - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: PanicServer - - Description: Panics the server. - - Parameters: const TTestServerPanic aPanic: in: Panic code - - Return Values: None - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -void CTestServer::PanicServer( const TTestServerPanic aPanic ) - { - -#ifdef USE_LOGGER - // Check if logger is available, if so, use it. - CStifLogger* log = (CStifLogger*) Dll::Tls(); - if ( log ) - { - log->Log( CStifLogger::ERed, _L("TestServer.DLL Panic %d"), aPanic); - } -#endif - - RDebug::Print( _L( "CTestServer::PanicServer" ) ); - _LIT( KTxtTestServer,"CTestServer" ); - User::Panic( KTxtTestServer,aPanic ); - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: NewL - - Description: Returns new CTestServer object - - Parameters: const TFileName& aName: in: Server name - - Return Values: None - - Errors/Exceptions: Leaves if memory allocation, ConstructL or StartL leaves. - - Status: Approved - -------------------------------------------------------------------------------- -*/ -CTestServer* CTestServer::NewL( const TFileName& aName ) - { - - CTestServer* self = new( ELeave ) CTestServer(); - CleanupStack::PushL( self ); - - // Construct the server - self->ConstructL( aName ); - - // Start the server - self->StartL( aName ); - - CleanupStack::Pop( self ); - - return self; - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: ConstructL - - Description: Second level constructor. Obtains pointer to library - entrypoint. - - Parameters: const TFileName& aName: in: Server name - - Return Values: None - - Errors/Exceptions: Leaves if entrypoint can't be obtained. - - Status: Approved - -------------------------------------------------------------------------------- -*/ -void CTestServer::ConstructL( const TFileName& aName ) - { - // Construct heap buffer for configuration file - iModuleNameBuffer = HBufC::NewL( aName.Length() ); - iModuleName.Set ( iModuleNameBuffer->Des() ); - iModuleName.Copy ( aName ); - - iContainerIndex = CObjectConIx::NewL(); - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: CTestServer - - Description: Constructor. - - Initialises non-zero member variables and base class with correct - priority. - - Parameters: None - - Return Values: None - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -CTestServer::CTestServer() : CServer2( CTestServer::ETestServerPriority ), - iModuleName(0, 0), - iSessionCount( 0 ) - { - iFirstTime = ETrue; - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: ~CTestServer - - Description: Destructor - Frees memory. - - Parameters: None - - Return Values: None - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -CTestServer::~CTestServer() - { - - delete iModuleNameBuffer; - iModuleNameBuffer = NULL; - - delete iContainerIndex; - iContainerIndex = NULL; - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: NewContainerL - - Description: Returns new container. Used to store subsessions - - Parameters: None - - Return Values: CObjectCon* New object container - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -CObjectCon* CTestServer::NewContainerL() - { - - CObjectCon* container = iContainerIndex->CreateL(); - - iSessionCount++; - - return container; - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: DeleteContainer - - Description: Deletes a container. - - Parameters: CObjectCon* aContainer: in: Container to be removed - - Return Values: None - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -void CTestServer::DeleteContainer( CObjectCon* aContainer ) - { - iContainerIndex->Remove( aContainer ); - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: SessionClosed - - Description: Inform Server that session is closed. - - Parameters: None - - Return Values: None - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -void CTestServer::SessionClosed() - { - // Decrease session count - iSessionCount--; - - // Check if last session is closed - if ( iSessionCount <= 0 ) - { - // Stop the active scheduler - // Execution will continue in ThreadFunction() - CActiveScheduler::Stop(); - } - - } -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: NewSessionL - - Description: Returns new session. - - Parameters: const TVersion &aVersion: in: Version required - - Return Values: CSharableSession* New session - - Errors/Exceptions: Leaves if invalid version or CTestModule construction - leaves - - Status: Approved - -------------------------------------------------------------------------------- -*/ -CSession2* CTestServer::NewSessionL( const TVersion& aVersion, - const RMessage2& /*aMessage*/ ) const - { - // check version is ok - TVersion v( KTestServerMajorVersionNumber, - KTestServerMinorVersionNumber, - KTestServerBuildVersionNumber - ); - if( !User::QueryVersionSupported( v,aVersion ) ) - { - User::Leave( KErrNotSupported ); - } - - return CTestModule::NewL( ( CTestServer* ) this ); - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: ModuleName - - Description: Returns module name - - Parameters: None - - Return Values: const TDesC&* Module name - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -const TDesC& CTestServer::ModuleName() const - { - return iModuleName; - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: FirstTime - - Description: Is module already once initialised. - - Parameters: None - - Return Values: TBool Has module initialized? - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -//@spe const TBool CTestServer::FirstTime() const -TBool CTestServer::FirstTime() const - { - return iFirstTime; - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: ClearFirstTime - - Description: Clear module first time flag. - - Parameters: None - - Return Values: None - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -void CTestServer::ClearFirstTime() - { - iFirstTime = EFalse; - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: ThreadFunction - - Description: The thread function, where Test Server lives in - - Parameters: TAny* aStarted: in: Start-up information - - Return Values: TInt Result from test module - - Errors/Exceptions: Clean-up stack can't be created because cannot - leave, error checks are done locally. - Panics if: - invalid start-up information - Test Server can't be started - - Status: Approved - -------------------------------------------------------------------------------- -*/ -TInt CTestServer::ThreadFunction( TAny* aStarted ) - { - - __UHEAP_MARK; - - TInt error( KErrNone ); - - // Get start-up information - TThreadStartTestServer* startInfo = ( TThreadStartTestServer* ) aStarted; - __ASSERT_ALWAYS( startInfo,PanicServer( ENoStartupInformation ) ); - - // Create clean-up stack - CTrapCleanup* tc = CTrapCleanup::New(); - __ASSERT_ALWAYS( tc, PanicServer(ECreateTrapCleanup)); - - // Construct the logger - TName path = _L("C:\\logs\\testframework\\testserver\\"); - TFileName name = _L("testserver_"); - name.Append ( startInfo->iName ); - - // Create logger, in Wins use HTML in HW default logger - TLoggerSettings loggerSettings; - - // Directory must create by hand if test server log wanted - loggerSettings.iCreateLogDirectories = EFalse; - - loggerSettings.iOverwrite = ETrue; - loggerSettings.iTimeStamp = ETrue; - loggerSettings.iLineBreak = ETrue; - loggerSettings.iEventRanking = EFalse; - loggerSettings.iThreadId = EFalse; - loggerSettings.iHardwareFormat = CStifLogger::ETxt; -#ifndef FORCE_STIF_INTERNAL_LOGGING_TO_RDEBUG - loggerSettings.iEmulatorFormat = CStifLogger::EHtml; - loggerSettings.iHardwareOutput = CStifLogger::EFile; - loggerSettings.iEmulatorOutput = CStifLogger::EFile; -#else - RDebug::Print( _L( "STIF Test Server logging forced to RDebug" ) ); - loggerSettings.iEmulatorFormat = CStifLogger::ETxt; - loggerSettings.iHardwareOutput = CStifLogger::ERDebug; - loggerSettings.iEmulatorOutput = CStifLogger::ERDebug; -#endif - loggerSettings.iUnicode = EFalse; - loggerSettings.iAddTestCaseTitle = EFalse; - - CStifLogger* logger = NULL; - TRAP ( error, logger = CStifLogger::NewL( path, name, loggerSettings ) ); - - // Thread Local Storage is used for get pointer to logger. - Dll::SetTls ( logger ); - - __TRACE( KInit,( _L( "TestServer.DLL server starting" ) ) ); - __TRACE( KInit,( CStifLogger::EBold, _L( "Loading module: %S"), &startInfo->iName ) ); - - RLibrary module; - TInt ret = KErrNone; - - TFileName newNameBuffer; - TInt check = CheckModuleName( startInfo->iName, newNameBuffer ); - if( check == KErrNone ) - { - // Load the module(TestScripter) - ret = module.Load( newNameBuffer ); - } - else - { - RemoveOptionalIndex(startInfo->iName, newNameBuffer); - __TRACE(KInit, (CStifLogger::EBold, _L( "Valid module name is [%S] (extracted from [%S])"), &newNameBuffer, &startInfo->iName)); - // Load the module(Others) - ret = module.Load(newNameBuffer); - } - - // If test module loading fails, do not start server - if( ret != KErrNone ) - { - __TRACE( KError,( CStifLogger::ERed, _L( "Test module loading failed, code = %d" ), ret ) ); - __TRACE( KError,( _L( "Check that module is compiled properly and stored to correct directory and all DLLs that it requires are available" ) ) ); - - // Error will be handled in StartNewServer - startInfo->iStartupResult = ret; - startInfo->iStarted.Signal(); - if ( !startInfo->iInNewThread ) - { - startInfo->iStarted.Close(); - } - module.Close(); - Dll::FreeTls(); - // Delete logger - delete logger; - logger = NULL; - // Delete clean-up stack - delete tc; - tc = NULL; - __UHEAP_MARKEND; - return ret; - } - else - { - __TRACE( KInit,( _L( "Test module loaded correctly" ) ) ); - } - - // Verify that there is function - CTestInterfaceFactory libEntry = ( CTestInterfaceFactory ) module.Lookup( 1 ); - if( libEntry == NULL ) - { - // Error will be handled in StartNewServer - __TRACE( KError,( CStifLogger::ERed, _L( "Can't find entrypoint from test module" ) ) ); - - startInfo->iStartupResult = KErrNotFound; - startInfo->iStarted.Signal(); - if ( !startInfo->iInNewThread ) - { - startInfo->iStarted.Close(); - } - module.Close(); - Dll::FreeTls(); - // Delete logger - delete logger; - logger = NULL; - // Delete clean-up stack - delete tc; - tc = NULL; - __UHEAP_MARKEND; - return KErrNotFound; - } - - module.Close(); - - // Construct and install active scheduler - CActiveScheduler* scheduler = new CActiveScheduler; - __ASSERT_ALWAYS( scheduler, PanicServer( EMainSchedulerError ) ); - CActiveScheduler::Install( scheduler ); - - // Construct server - CTestServer* server = NULL; - TRAPD( err, server = CTestServer::NewL( startInfo->iName ) ); - __ASSERT_ALWAYS( !err, PanicServer( ESvrCreateServer ) ); - - server->iUiTesting = startInfo->iUiTesting; - server->iTestThreadContainerRunnerFactory = startInfo->iTestThreadContainerRunnerFactory; - - // Inform that we are up and running - startInfo->iStartupResult = KErrNone; - startInfo->iStarted.Signal(); - if ( !startInfo->iInNewThread ) - { - startInfo->iStarted.Close(); - } - - // Start handling requests - CActiveScheduler::Start(); - - // Execution continues from here after CActiveScheduler::Stop - - __TRACE( KVerbose,( _L( "TestServer.DLL active scheduler stopped" ) ) ); - - // Delete the server - delete server; - server = NULL; - __TRACE( KVerbose,( _L( "TestServer.DLL server object deleted" ) ) ); - - delete scheduler; - scheduler = NULL; - __TRACE( KVerbose,( _L( "Active scheduler deleted" ) ) ); - - __TRACE ( KInit, (_L("TestServer.DLL ThreadFunction exiting, server closing")) ); - - Dll::FreeTls(); - // Delete logger - delete logger; - logger = NULL; - // Delete clean-up stack - delete tc; - tc = NULL; - - __UHEAP_MARKEND; - - return KErrNone; - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: GetServerThreadId - - Description: Returns server thread id - - Parameters: None - - Return Values: TInt : thread id - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -TInt CTestServer::GetServerThreadId() - { - RThread thread; - return thread.Id(); - - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: GetTestThreadContainerRunnerFactory - - Description: Returns server thread id - - Parameters: None - - Return Values: TInt : thread id - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -CTestThreadContainerRunnerFactory* CTestServer::GetTestThreadContainerRunnerFactory() - { - - return iTestThreadContainerRunnerFactory; - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: UiTesting - - Description: Gets information if testserver supports UI testing - - Parameters: None - - Return Values: True if testserver supports UI testing, False if not. - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -TBool CTestServer::UiTesting() - { - - return iUiTesting; - } - -/* -------------------------------------------------------------------------------- - - Class: CTestServer - - Method: GetUiEnvProxy - - Description: Gets UIEnvProxy - - Parameters: None - - Return Values: Pointer to UIEnvProxy. - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -CUiEnvProxy* CTestServer::GetUiEnvProxy() - { - - return iTestThreadContainerRunnerFactory->GetUiEnvProxy(); - } - - -// ================= OTHER EXPORTED FUNCTIONS ================================= - -/* -------------------------------------------------------------------------------- - - Class: - - - Method: StartNewServer - - Description: Starts a new server. Server will be running its own - thread and this functions returns when server is up and running or - server start-up fails. - - Parameters: const TFileName& aModuleFileName: in: Module name - TFileName& aServerName: in: Server name - const TBool aInNewThread: in: Is new thread - RSemaphore aSynchronisation: in: For synchronisation - TBool aUiTestingServer: in: Indicates if testserver should support UI testing - CTestThreadContainerRunnerFactory* aTestThreadContainerRunnerFactory: in: Pointer to runner factory - - Return Values: TInt: Symbian error code - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -EXPORT_C TInt StartNewServer( const TFileName& aModuleFileName, - TFileName& aServerName, - const TBool aInNewThread, - RSemaphore aSynchronisation, - TBool aUiTestingServer, - CTestThreadContainerRunnerFactory* aTestThreadContainerRunnerFactory - ) - { - - __UHEAP_MARK; - - //Check server not already started - TFindServer findServer( aModuleFileName ); - TFullName name; - if( findServer.Next( name ) == KErrNone ) - { - // Server already started, nothing to do - aServerName = aModuleFileName; - __UHEAP_MARKEND; - return KErrAlreadyExists; - } - - // Construct start-up information object - TThreadStartTestServer* startInfo = new TThreadStartTestServer(); - if( startInfo == NULL ) - { - __UHEAP_MARKEND; - return KErrNoMemory; - } - - // Fill the start-up information - startInfo->iName = aModuleFileName; - startInfo->iStartupResult = KErrNone; - startInfo->iStarted = aSynchronisation; - startInfo->iInNewThread = aInNewThread; - startInfo->iUiTesting = aUiTestingServer; - startInfo->iTestThreadContainerRunnerFactory = aTestThreadContainerRunnerFactory; - - // EKA1 - if ( aInNewThread ) - { - // Create thread - TInt res = startInfo->iServerThread.Create( - startInfo->iName , // Name of thread - CTestServer::ThreadFunction, // Thread function - KDefaultStackSize, // Stack size - KDefaultHeapSize, // Heap initial size - KMaxHeapSize, // Heap start max size - startInfo // Parameter to thread function - ); - - // If thread creation failed - if( res != KErrNone ) - { - startInfo->iStarted.Close(); // Close semaphore - delete startInfo; - startInfo = NULL; - __UHEAP_MARKEND; - return res; - } - - // Now start thread - startInfo->iServerThread.SetPriority( EPriorityMuchMore ); - startInfo->iServerThread.Resume(); - - // Wait until the thread is started - startInfo->iStarted.Wait(); - - // Server is started( or it has returned error ) - - - } - - // EKA2 and EKA1's HW - else - { - // Call directly thread function, this starts server and - // blocks this thread. - // Priority is default, not known reason why should be greater - // than default priority (Work over a year). - CTestServer::ThreadFunction( startInfo ); - } - - // Set server name - aServerName = aModuleFileName; - - // Free memory - TInt r = startInfo->iStartupResult; - startInfo->iServerThread.Close(); - startInfo->iStarted.Close(); - delete startInfo; - startInfo = NULL; - - __UHEAP_MARKEND; - - // Return start-up result. - return r; - - } - -/* -------------------------------------------------------------------------------- - - Class: - - - Method: StartNewServer - - Description: Starts a new server. Server will be running its own - thread and this functions returns when server is up and running or - server start-up fails. - - Parameters: const TFileName& aModuleFileName: in: Module name - TFileName& aServerName: in: Server name - const TBool aInNewThread: in: Is new thread - RSemaphore aSynchronisation: in: For synchronisation - - Return Values: TInt: Symbian error code - - Errors/Exceptions: None - - Status: Approved - -------------------------------------------------------------------------------- -*/ -EXPORT_C TInt StartNewServer( const TFileName& aModuleFileName, - TFileName& aServerName, - const TBool aInNewThread, - RSemaphore aSynchronisation - ) - { - - return StartNewServer( aModuleFileName, aServerName, aInNewThread, aSynchronisation, false, NULL ); - } - - -/* -------------------------------------------------------------------------------- - - Class: - - - Method: StartNewServer - - Description: Starts a new server. Server will be running its own - thread and this functions returns when server is up and running or - server start-up fails. - - Parameters: const TFileName& aName: in: Module name to be used - TFileName& aServerName: out: The name of the server - - Return Values: TInt Error code / KErrNone - - Errors/Exceptions: None - - Status: Proposal - -------------------------------------------------------------------------------- -*/ -EXPORT_C TInt StartNewServer( const TFileName& aModuleFileName, - TFileName& aServerName - ) - { - - __UHEAP_MARK; - - RMutex startupMutex; - TInt ret( KErrNone ); - // Global mutex already created(see CTestEngineServer::ThreadFunction). - // Open global mutex. - ret = startupMutex.OpenGlobal( KStifTestServerStartupMutex ); - if( ret != KErrNone ) - { - // Not able to open mutex - return ret; - } - - startupMutex.Wait(); - - //Check server not already started - TFindServer findServer( aModuleFileName ); - TFullName name; - if( findServer.Next( name ) == KErrNone ) - { - // Server already started, nothing to do - aServerName = aModuleFileName; - - // release startupmutex - startupMutex.Signal(); - startupMutex.Close(); - - __UHEAP_MARKEND; - return KErrAlreadyExists; - } - - RSemaphore startupSemaphore; - startupSemaphore.CreateLocal( 0 ); - - // Start server in new thread - TInt r = StartNewServer ( aModuleFileName, aServerName, ETrue, startupSemaphore ); - - // startupSemaphore will be closed inside StartNewServer when start-up is done. - - // release startupmutex - startupMutex.Signal(); - startupMutex.Close(); - - __UHEAP_MARKEND; - - // Return start-up result. - return r; - - } - -// End of File