sysstatemgmt/systemstatemgr/test/tssm/src/tssm_step_swptransitionengine.cpp
changeset 0 4e1aa6a622a0
child 21 ccb4f6b3db21
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysstatemgmt/systemstatemgr/test/tssm/src/tssm_step_swptransitionengine.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,459 @@
+// Copyright (c) 2007-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:
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Symbian test code
+*/
+
+
+#include <ssm/ssmcommandlist.h>
+
+#include "ssmswppolicyframe.h"
+#include "ssmswptransitionengine.h"
+
+#include "ssmatest_utils.h"
+#include "tssm_step_swptransitionengine.h"
+#include "tssm_swppolicy_generic.h"
+#include "tssm_swppolicy_generic.hrh"
+
+#include <e32debug.h>
+
+// Keys and values used for testing the transition engines
+static const TUint KSwpTestKey1 = 0xE5325221;
+
+const TInt KTestErrorBadCategory = -911;
+const TInt KTestErrorBadFunction = -912;
+
+/**
+*/
+static TInt StopScheduler(TAny* aSsmSwpTransitionEngineTest)
+	{
+	CSsmSwpTransitionEngineTest*  ssmSwpRequestEngineTest = static_cast<CSsmSwpTransitionEngineTest*>(aSsmSwpTransitionEngineTest);
+	ssmSwpRequestEngineTest->StopActiveScheduler();
+	return KErrNone;
+	}
+
+//--------------------- Thread creation framework ---------------------
+
+/**
+Test framework to check for panic scenarios
+It requires to create a separate thread so we can check the panic category and code.
+*/
+TInt StartTestInThreadL(TInt aFunction)
+	{
+	RThread thread;
+	// Give each thread a unique name to avoid KErrAlreadyExists error on thread creation
+	_LIT(KThreadNamePrefix, "SsmTestThread");
+	RBuf threadName;
+	CleanupClosePushL(threadName);
+	threadName.CreateL(KThreadNamePrefix().Length() + 4); // 4 digit thread number
+	threadName = KThreadNamePrefix;
+	threadName.AppendNumFixedWidth(aFunction, EDecimal, 4);
+	const TInt KMinHeapSize = 0xc800; // 50k - NOTE just an arbitrary value, please feel free to change it
+	const TInt KMaxHeapSize = 0x19000; // 100k - NOTE just an arbitrary value, please feel free to change it
+	User::LeaveIfError(thread.Create(threadName, ThreadStartFn, KDefaultStackSize, KMinHeapSize, KMaxHeapSize, (TAny*)aFunction));
+	CleanupStack::PopAndDestroy(&threadName);
+	TRequestStatus status;
+	thread.Logon(status);
+	TBool jit =	User::JustInTime();
+	User::SetJustInTime(EFalse);
+	thread.Resume();
+	User::WaitForRequest(status);
+
+	// always expecting a transition engine panic
+	TExitCategoryName category = thread.ExitCategory();
+	RDebug::Print(_L("***** Exit Category = %S *****"),&category);
+	if (category.Compare(KPanicSysStateMgr) != 0)
+		{
+		User::Leave(KTestErrorBadCategory);
+		}
+	const TInt exitReason = thread.ExitReason();
+	thread.Close();
+	User::SetJustInTime(jit);
+
+	// return the exit reason for the caller to verify the expected panic value
+	return exitReason;
+	}
+
+TInt ThreadStartFn(TAny* aPtr)
+	{
+	CTrapCleanup* trapCleanup = CTrapCleanup::New();
+	if (!trapCleanup)
+		{
+		return KErrNoMemory;
+		}
+
+	TInt function = (TInt)aPtr;
+	TRAPD(err, ThreadDispatchFunctionL(function));
+
+	delete trapCleanup;
+	return err;
+	}
+
+
+void ThreadDispatchFunctionL(TInt aFunction)
+	{
+	switch (aFunction)
+		{
+		case EThreadSubmitTwice:
+			ThreadSubmitTwiceL();
+			break;
+		default:
+			User::Leave(KTestErrorBadFunction);
+			break;
+		}
+	}
+
+
+void ThreadSubmitTwiceL()
+	{
+	CSsmSwpTransitionEngineTest* step = new (ELeave) CSsmSwpTransitionEngineTest();
+
+	CActiveScheduler* activeScheduler = new(ELeave) CActiveScheduler;
+	CleanupStack::PushL(activeScheduler);
+	CActiveScheduler::Install(activeScheduler);
+
+	CAsyncCallBack* asyncStopScheduler = new(ELeave) CAsyncCallBack(CActive::EPriorityIdle);
+	TCallBack stop(StopScheduler, step);
+	asyncStopScheduler->Set(stop);
+	CleanupStack::Pop(activeScheduler);
+
+	// ssmswppolicyproxy is created and set by the individualtransitionscheduler, since
+	// we are submitting the request directly to the engine the ssmswppolicyproxy should be
+	// created and set in the engine
+	CSsmSwpPolicyCliSession* ssmSwpPolicySession = CSsmSwpPolicyCliSession::NewL();
+	CleanupStack::PushL(ssmSwpPolicySession);
+
+	// Setting the cle session as we have to execute the publishswp command.
+	// published swp value is used to stop the scheduler.
+	CCleSessionProxy* cleSession = CCleSessionProxy::NewL();
+	CleanupStack::PushL(cleSession);
+
+	const TSsmSwp swpValue(KSwpTestKey1, ESwpGenericDoNothing);
+	CSsmSwpPolicyFrame* policy = step->GetSwpPolicyL(swpValue);
+	CleanupStack::PushL(policy);
+
+	CSsmSwpTransitionEngine* engine = CSsmSwpTransitionEngine::NewL(swpValue);
+	engine->SetCleSessionProxy(cleSession);
+	engine->SetSwpPolicyFrame(policy);
+	engine->SetSsmSwpPolicySession(ssmSwpPolicySession);
+	CleanupStack::Pop(policy);
+
+	CleanupStack::PushL(engine);
+	engine->Submit();
+	engine->Submit();
+	// etc, etc, etc..
+	// don't bother to continue here. All being well the second SubmitL will cause a panic!
+	//Cleanup test
+	CleanupStack::PopAndDestroy(3, ssmSwpPolicySession);	// and engine
+	}
+
+
+//----------------- CTestStep implemenation --------------------
+
+/**
+*/
+CSsmSwpTransitionEngineTest::~CSsmSwpTransitionEngineTest()
+	{
+	iProperty.Close();
+	delete iAsyncStopScheduler;
+	delete iActiveScheduler;
+	}
+
+/**
+*/
+CSsmSwpTransitionEngineTest::CSsmSwpTransitionEngineTest()
+	{
+	SetTestStepName(KTSsmSwpTransitionEngineStep);
+	}
+
+/**
+*/
+TVerdict CSsmSwpTransitionEngineTest::doTestStepPreambleL()
+	{
+	iActiveScheduler = new(ELeave) CActiveScheduler;
+	CActiveScheduler::Install (iActiveScheduler);
+
+	iAsyncStopScheduler = new(ELeave) CAsyncCallBack(CActive::EPriorityIdle);
+	TCallBack stop(StopScheduler, this);
+	iAsyncStopScheduler->Set(stop);
+
+	return CTestStep::doTestStepPreambleL();
+	}
+
+/**
+Old Test CaseID 		APPFWK-SSM-0007
+New Test CaseID 		DEVSRVS-SSMA-SSM-0007
+ */
+
+TVerdict CSsmSwpTransitionEngineTest::doTestStepL()
+	{
+	INFO_PRINTF1(_L("CSsmSwpTransitionEngineTest started...."));
+
+	__UHEAP_MARK;
+
+	doTestSwpTransitionEngineTestForMemoryLeaksL();
+	doTestRequestSimpleL();
+	doTestRequestCancelL();
+	doTestRequestSubmitTwiceL();
+
+	__UHEAP_MARKEND;
+
+	INFO_PRINTF1(_L("....CSsmSwpTransitionEngineTest completed!!"));
+	return TestStepResult();
+	}
+
+/**
+*/
+TVerdict CSsmSwpTransitionEngineTest::doTestStepPostambleL()
+	{
+	return CTestStep::doTestStepPostambleL();
+	}
+
+/**
+*/
+void CSsmSwpTransitionEngineTest::doTestSwpTransitionEngineTestForMemoryLeaksL()
+	{
+	INFO_PRINTF1(_L("Checking for destructor memoryleaks in CSsmSwpTransitionEngine"));
+
+	__UHEAP_MARK;
+
+	// ssmswppolicyproxy is created and set by the individualtransitionscheduler, since
+	// we are submitting the request directly to the engine the ssmswppolicyproxy should be
+	// created and set in the engine
+	CSsmSwpPolicyCliSession* ssmSwpPolicySession = CSsmSwpPolicyCliSession::NewL();
+	CleanupStack::PushL(ssmSwpPolicySession);
+
+	// Setting the cle session as we have to execute the publishswp command.
+	// published swp value is used to stop the scheduler.
+	CCleSessionProxy* cleSession = CCleSessionProxy::NewL();
+	CleanupStack::PushL(cleSession);
+
+	const TSsmSwp swpValue(KSwpTestKey1, ESwpGenericDoNothing);
+	CSsmSwpPolicyFrame* policy = this->GetSwpPolicyL(swpValue);
+	CleanupStack::PushL(policy);
+
+	CSsmSwpTransitionEngine* engine = CSsmSwpTransitionEngine::NewL(swpValue);
+	engine->SetCleSessionProxy(cleSession);
+	engine->SetSwpPolicyFrame(policy);
+	engine->SetSsmSwpPolicySession(ssmSwpPolicySession);
+	CleanupStack::Pop(policy);
+	
+	//Cleanup test
+	CleanupStack::PopAndDestroy(2, ssmSwpPolicySession);
+	delete engine;
+
+	__UHEAP_MARKEND;
+	}
+
+/**
+Takes CSsmSwpTransitionEngine through the simple swp transition.
+*/
+void CSsmSwpTransitionEngineTest::doTestRequestSimpleL()
+	{
+	INFO_PRINTF1(_L("Checking requesthandler with a single request"));
+
+	__UHEAP_MARK;
+
+	// ssmswppolicyproxy is created and set by the individualtransitionscheduler, but
+	// we are submitting the request directly to the engine the ssmswppolicyproxy should be
+	// created and set in the engine
+	CSsmSwpPolicyCliSession* ssmSwpPolicySession = CSsmSwpPolicyCliSession::NewL();
+	CleanupStack::PushL(ssmSwpPolicySession);
+
+	// Setting the cle session as we have to execute the publishswp command.
+	// published swp value is used to stop the scheduler.
+	CCleSessionProxy* cleSession = CCleSessionProxy::NewL();
+	CleanupStack::PushL(cleSession);
+
+	// Define and set the rproperty
+	TEST(KErrNone == iProperty.Define(RProcess().SecureId(), KSwpTestKey1, RProperty::EInt));
+	TEST(KErrNone == iProperty.Set(RProcess().SecureId(), KSwpTestKey1, 0));
+
+	TInt value;
+	TEST(KErrNone == iProperty.Get(RProcess().SecureId(), KSwpTestKey1, value));
+	TEST(value == 0);
+
+	const TSsmSwp swpValue(KSwpTestKey1, ESwpGenericDoNothing);
+	CSsmSwpPolicyFrame* policy = this->GetSwpPolicyL(swpValue);
+	CleanupStack::PushL(policy);
+	
+	CSsmSwpTransitionEngine* engine = CSsmSwpTransitionEngine::NewL(swpValue);
+	engine->SetCleSessionProxy(cleSession);
+	engine->SetSwpPolicyFrame(policy);
+	engine->SetSsmSwpPolicySession(ssmSwpPolicySession);
+	engine->PerformCommandListValidation(EFalse);
+	CleanupStack::Pop(policy);
+
+	CleanupStack::PushL(engine);
+	engine->Submit();
+
+	//this callback will not run until the test is finished because it has priority idle
+	iAsyncStopScheduler->CallBack();
+	//run engine
+	iActiveScheduler->Start();
+
+	TEST(KErrNone == iProperty.Get(RProcess().SecureId(), KSwpTestKey1, value));
+	TEST(value == ESwpGenericDoNothing);
+
+	TEST(KErrNone == iProperty.Delete(RProcess().SecureId(), KSwpTestKey1));
+
+	//Cleanup test
+	CleanupStack::PopAndDestroy(3, ssmSwpPolicySession);	// and engine
+
+	__UHEAP_MARKEND;
+	}
+
+/**
+Takes CSsmSwpTransitionEngine through the simple swp transition and cancels it.
+*/
+void CSsmSwpTransitionEngineTest::doTestRequestCancelL()
+	{
+	INFO_PRINTF1(_L("Checking requesthandler with a cancel request"));
+
+	__UHEAP_MARK;
+
+	// ssmswppolicyproxy is created and set by the individualtransitionscheduler, but
+	// we are submitting the request directly to the engine the ssmswppolicyproxy should be
+	// created and set in the engine
+	CSsmSwpPolicyCliSession* ssmSwpPolicySession = CSsmSwpPolicyCliSession::NewL();
+	CleanupStack::PushL(ssmSwpPolicySession);
+
+	// Setting the cle session as we have to execute the publishswp command.
+	// published swp value is used to stop the scheduler.
+	CCleSessionProxy* cleSession = CCleSessionProxy::NewL();
+	CleanupStack::PushL(cleSession);
+
+	// Define and set the rproperty
+	TEST(KErrNone == iProperty.Define(RProcess().SecureId(), KSwpTestKey1, RProperty::EInt));
+	TEST(KErrNone == iProperty.Set(RProcess().SecureId(), KSwpTestKey1, -5));
+
+	TInt value;
+	TEST(KErrNone == iProperty.Get(RProcess().SecureId(), KSwpTestKey1, value));
+	TEST(value == -5);
+
+	const TSsmSwp swpValue(KSwpTestKey1, ESwpGenericDoNothing);
+	CSsmSwpPolicyFrame* policy = this->GetSwpPolicyL(swpValue);
+	CleanupStack::PushL(policy);
+
+	CSsmSwpTransitionEngine* engine = CSsmSwpTransitionEngine::NewL(swpValue);
+	engine->SetCleSessionProxy(cleSession);
+	engine->SetSwpPolicyFrame(policy);
+	engine->SetSsmSwpPolicySession(ssmSwpPolicySession);
+	engine->PerformCommandListValidation(EFalse);
+	CleanupStack::Pop(policy);
+
+	CleanupStack::PushL(engine);
+	engine->Submit();
+	engine->Cancel();
+
+	//this callback will not run until the test is finished because it has priority idle
+	iAsyncStopScheduler->CallBack();
+	//run engine
+	iActiveScheduler->Start();
+
+	TEST(KErrNone == iProperty.Get(RProcess().SecureId(), KSwpTestKey1, value));
+	TEST(value == -5);
+
+	TEST(KErrNone == iProperty.Delete(RProcess().SecureId(), KSwpTestKey1));
+
+	//Cleanup test
+	CleanupStack::PopAndDestroy(3, ssmSwpPolicySession);	// and engine
+
+	__UHEAP_MARKEND;
+	}
+
+void CSsmSwpTransitionEngineTest::doTestRequestSubmitTwiceL()
+	{
+	INFO_PRINTF1(_L("Checking requesthandler with two consecutive requests"));
+	TInt exitReason(0);
+	TRAPD(err, exitReason = StartTestInThreadL(EThreadSubmitTwice));
+	TEST(err == KErrNone);
+	INFO_PRINTF2(_L("    3-- StartTestInThreadL method completed with '%d'."), err);
+	TEST(exitReason == ESwpTransitionEngineError3);
+	INFO_PRINTF3(_L("    3-- received panic '%d', expected was '%d'."), exitReason, ESwpTransitionEngineError3);
+
+	// this test raises panics due to negative testing - close them to clear the screen.
+	CloseAllPanicWindowsL();
+	}
+
+void CSsmSwpTransitionEngineTest::StopActiveScheduler()
+	{
+	// We would stop the sceduler once all the required transitions are completed
+	//Verify that the expected calls were made
+	TInt value;
+	TEST(KErrNone == iProperty.Get(RProcess().SecureId(), KSwpTestKey1, value));
+
+	// We have to stop the scheduler in case of Cancel test code, so testing property's initial value.
+	if (value == ESwpGenericDoNothing || value == -5)
+		{
+		CActiveScheduler::Stop();
+		}
+	else
+		{
+		iAsyncStopScheduler->CallBack();
+		}
+	}
+
+//----------------- MPolicyResolverProxy implementation --------------------
+
+CSsmSwpPolicyFrame* CSsmSwpTransitionEngineTest::CreatePolicyLC(const RLibrary& aLibrary) const
+	{
+	__ASSERT_DEBUG( KNullHandle != aLibrary.Handle(), PanicNow(KPanicSysStateMgr, ESwpPolicyResolverLibraryNotLoaded));
+	
+	CSsmSwpPolicyFrame* frame = NULL;
+	TRAPD(err, frame = CSsmSwpPolicyFrame::NewL(aLibrary.Lookup(1)));
+
+	if (err != KErrNone)
+		{
+		TFileName name = aLibrary.FileName();
+		DEBUGPRINT3(_L("Error %d when calling first function in State Policy DLL %S."), err, &name);
+		}
+	User::LeaveIfError(err);
+	CleanupStack::PushL(frame);
+	return frame;
+	}
+
+/**
+*/
+CSsmSwpPolicyFrame* CSsmSwpTransitionEngineTest::GetSwpPolicyL(const TSsmSwp& aSwp)
+	{
+	RLibrary library;
+	const TInt fileErr = library.Load(KTestSwpPolicyGenericFile);
+	if (fileErr != KErrNone)
+		{
+		RDebug::Print(_L("Failed to load library file %S, file error-code: %d"), &KTestSwpPolicyGenericFile(), fileErr);
+		User::Leave(fileErr);
+		}
+	
+	// make a process-owned copy of the handle as it has to be used by SsmSwpPolicyServer, 
+	// which runs in a separate thread
+	User::LeaveIfError(library.Duplicate(RThread(), EOwnerProcess));
+	
+	CSsmSwpPolicyFrame* policy = CreatePolicyLC(library);
+	CleanupStack::Pop(policy);
+	policy->SetLibrary(library); // takes ownership of open library handle
+	policy->SetSwpKey(aSwp.Key());
+	
+	RDebug::Print(_L("Created Swp Policy DLL %S"), &KTestSwpPolicyGenericFile());
+	
+	return policy;
+	}
+
+
+
+