sl@0: // Copyright (c) 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: //
sl@0: 
sl@0: #include <e32test.h>
sl@0: #include <e32debug.h>
sl@0: #include <bautils.h>
sl@0: #include <featurecontrol.h>
sl@0: #include "t_fmgrbursim.h"
sl@0: 
sl@0: ///////////////////////////////////////////////////////////////////////////////////////
sl@0: 
sl@0: RTest TheTest(_L("t_fmgrbackupresponse"));
sl@0: 
sl@0: const TUint threadTimeout = 2000000;    // thread timeout = 2 seconds 
sl@0: 
sl@0: static RSemaphore MainThreadCrS;
sl@0: static TBool featMgrIsResponsive = EFalse;
sl@0: 
sl@0: ///////////////////////////////////////////////////////////////////////////////////////
sl@0: ///////////////////////////////////////////////////////////////////////////////////////
sl@0: //Test macros and functions
sl@0: void Check1(TInt aValue, TInt aLine, TBool aPrintThreadName = EFalse)
sl@0:     {
sl@0:     if(!aValue)
sl@0:         {
sl@0:         //DeleteTestFiles();
sl@0:         if(aPrintThreadName)
sl@0:             {
sl@0:             RThread th;
sl@0:             TName name = th.Name();
sl@0:             RDebug::Print(_L("*** Thread %S, Line %d\r\n"), &name, aLine);
sl@0:             }
sl@0:         else
sl@0:             {
sl@0:             RDebug::Print(_L("*** Line %d\r\n"), aLine);
sl@0:             }
sl@0:         TheTest(EFalse, aLine);
sl@0:         }
sl@0:     }
sl@0: 
sl@0: void Check2(TInt aValue, TInt aExpected, TInt aLine, TBool aPrintThreadName = EFalse)
sl@0:     {
sl@0:     if(aValue != aExpected)
sl@0:         {
sl@0:         //DeleteTestFiles();
sl@0:         if(aPrintThreadName)
sl@0:             {
sl@0:             RThread th;
sl@0:             TName name = th.Name();
sl@0:             RDebug::Print(_L("*** Thread %S, Line %d Expected error: %d, got: %d\r\n"), &name, aLine, aExpected, aValue);
sl@0:             }
sl@0:         else
sl@0:             {
sl@0:             RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue);
sl@0:             }
sl@0:         TheTest(EFalse, aLine);
sl@0:         }
sl@0:     }
sl@0: #define TEST(arg) ::Check1((arg), __LINE__)
sl@0: #define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__)
sl@0: #define TTEST(arg) ::Check1((arg), __LINE__, ETrue)
sl@0: #define TTEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__, ETrue)
sl@0: 
sl@0: // ------------------------- ------------------------- 
sl@0: // setup and cleanup functions
sl@0: 
sl@0: TInt TestThreadL(void*)
sl@0:     {
sl@0:         __UHEAP_MARK;
sl@0:         
sl@0:         CTrapCleanup* tc = CTrapCleanup::New();
sl@0:         RFeatureControl rfc;
sl@0:         TTEST2( rfc.Connect(), KErrNone );
sl@0:         
sl@0:         // During backup, feature manager server should be responsive and return KErrServerBusy for write request 
sl@0:         TInt err = rfc.EnableFeature( TUid::Uid(0x00000001) );
sl@0:         TTEST2(err, KErrServerBusy);
sl@0:         
sl@0:         // During backup, feature manager server should be responsive and NOT return KErrServerBusy for read request
sl@0:         err = rfc.FeatureSupported( TUid::Uid(0x00000001) );
sl@0:         TTEST(err != KErrServerBusy);
sl@0: 		
sl@0:         rfc.Close();
sl@0:         featMgrIsResponsive = ETrue;
sl@0:         RDebug::Print(_L("+++:TestThread: Query and Modification completed\r\n"));
sl@0:         MainThreadCrS.Signal();
sl@0:         delete tc;
sl@0:         
sl@0:         __UHEAP_MARKEND;
sl@0:         
sl@0:         return KErrNone;
sl@0:     }
sl@0: /**
sl@0: @SYMTestCaseID          PDS-EFM-CT-4057
sl@0: @SYMTestCaseDesc        Querying and modifying a feature during backup operation.
sl@0:                         Verify that a response is returned from the server during backup.
sl@0: @SYMTestPriority        High
sl@0: @SYMTestActions         Start simulating backup operation
sl@0:                         Create a thread that will:
sl@0:                         Modify a feature and verify that a response (KErrServerBusy) is received 
sl@0:                         Query a feature and verify that a response is received (doesn't matter what the result is)
sl@0:                         The thread should finished in less than 2 seconds.
sl@0:                         Otherwise the test fail.          
sl@0: @SYMTestExpectedResults Test must not fail
sl@0: @SYMREQ                 
sl@0: */  
sl@0: void TestBackupResponseL()
sl@0:     {
sl@0:         _LIT(KThreadName, "BakTh");
sl@0:         featMgrIsResponsive = EFalse;
sl@0:         
sl@0:         CFeatMgrBURSim* simulate = CFeatMgrBURSim::NewLC();
sl@0:         RThread testThread;
sl@0:         TRequestStatus testStatus;
sl@0:         CleanupClosePushL( testThread );
sl@0:         
sl@0:         //Needs to ensure server is started before simulating backup operation
sl@0:         RFeatureControl rfc;
sl@0:         TTEST2( rfc.Connect(), KErrNone ); //This will start the server if not already started
sl@0:         rfc.Close();
sl@0:         
sl@0:         simulate->Simulate_CheckRegFileL();
sl@0:         
sl@0:         // Simulate a backup
sl@0:         RDebug::Print(_L("Simulating Backup of FeatMgr\r\n"));
sl@0:         simulate->Simulate_StartBackupL();
sl@0: 
sl@0:         TEST2( testThread.Create(KThreadName, &TestThreadL, 0x2000, 0x1000, 0x10000, NULL, EOwnerProcess), KErrNone );
sl@0:         testThread.Logon(testStatus);
sl@0:         TEST2( testStatus.Int(), KRequestPending );
sl@0:         testThread.Resume();
sl@0:         // Wait for 1.5 second for the query thread to finish. 
sl@0:         RDebug::Print(_L("+++:MainThread: Wait for query and modification completion...\r\n"));
sl@0:         MainThreadCrS.Wait(threadTimeout);
sl@0:         // If query is responsive within the 1.5 second frame the following check should pass.
sl@0:         TEST (featMgrIsResponsive);
sl@0:         simulate->Simulate_EndBackupL();
sl@0:         
sl@0:         CleanupStack::PopAndDestroy(&testThread);
sl@0:         CleanupStack::PopAndDestroy(simulate);
sl@0:     }
sl@0: 
sl@0: ////////////////////////////////////////////////////////////////////////////////////
sl@0: void DoTestsL()
sl@0: 	{
sl@0:     MainThreadCrS.CreateLocal(0);
sl@0:     
sl@0:     TheTest.Start(_L(" @SYMTestCaseID:PDS-EFM-CT-4057 Backup Query and Modification Response"));
sl@0:     TestBackupResponseL();
sl@0:     
sl@0:     MainThreadCrS.Close();
sl@0: 
sl@0: 	}
sl@0: 
sl@0: TInt E32Main()
sl@0: 	{
sl@0: 	TheTest.Title();
sl@0: 	
sl@0: 	CTrapCleanup* tc = CTrapCleanup::New();
sl@0: 	
sl@0: 	__UHEAP_MARK;
sl@0: 	
sl@0: 	TRAPD(err, DoTestsL());
sl@0: 	TEST2(err, KErrNone);
sl@0: 
sl@0: 	__UHEAP_MARKEND;
sl@0: 	
sl@0: 	TheTest.End();
sl@0: 	TheTest.Close();
sl@0: 	
sl@0: 	delete tc;
sl@0: 	
sl@0: 	User::Heap().Check();
sl@0: 	return KErrNone;
sl@0: 	}