tzservices/tzserver/test/Common/src/DstStep.cpp
changeset 0 2e3d3ce01487
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tzservices/tzserver/test/Common/src/DstStep.cpp	Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,422 @@
+// Copyright (c) 2004-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:
+//
+
+#include "DstStep.h"
+
+// Type definitions
+#define UNUSED_VAR(a) a = a
+ 
+const TInt KErrTestFileHandle = -7400;
+
+_LIT(KRunTestCount, "MaxRunLimit");
+_LIT(KLeakTestCount, "MaxOOMLimit");
+_LIT(KFirstLeakIter, "MinOOMLimit");
+_LIT(KFileTestCount, "MaxOOFLimit");
+_LIT(KCheckHandles, "CheckHandles");
+
+_LIT(KNormalTestStarted, "Normal Test Started");
+_LIT(KNormalTestComplete, "Normal Test Completed; Attempts: %d");
+_LIT(KOOMTestStarted, "Out-of-Memory test started");
+_LIT(KOOMTestTerminated, "Out-of-Memory test ended; Allocations made: %d");
+_LIT(KOOFTestStarted, "Out-of-File-Handle Test Started");
+_LIT(KOOFTestTerminated, "Out-of-File-Handle test ended; Handles used: %d");
+_LIT(KOOFTestAborted, "Out-of-File-Handle Test Aborted; No File Session supplied.");
+
+
+//
+// CDSTActiveWorker
+//
+CDSTActiveWorker::~CDSTActiveWorker()
+	{
+	Deque();
+	}
+
+CDSTActiveWorker::CDSTActiveWorker(const CDstStep& aTestStep) : 
+	CActive(CActive::EPriorityStandard), iTestStep(const_cast<CDstStep&>(aTestStep))
+	{}
+
+void CDSTActiveWorker::Start()
+	{
+	CompleteSelf();
+	}
+
+
+void CDSTActiveWorker::CompleteSelf()
+	{
+	SetActive();
+	TRequestStatus* status = &iStatus;
+	User::RequestComplete(status,KErrNone);
+	}
+
+CDSTActiveWorker* CDSTActiveWorker::NewL(const CDstStep& aTestStep)
+	{
+	CDSTActiveWorker* self = new(ELeave) CDSTActiveWorker(aTestStep);
+	CActiveScheduler::Add(self);
+	self->CompleteSelf();
+	return self;
+	}
+
+void CDSTActiveWorker::RunL()
+	{
+	iTestStep.RunTest();
+	}
+
+void CDSTActiveWorker::DoCancel()
+	{
+	// do nothing
+	}
+
+TInt CDSTActiveWorker::RunError(TInt aError)
+	{
+	iTestStep.TestCompleted(aError);
+	return KErrNone;
+	}
+
+//
+// CDstStep
+//
+CDstStep::CDstStep() : 
+	iState(ERunningNormalTest),
+	iTestCmd(ECreateUnit),
+	iMaxRunTestCount (1),				
+	iMaxLeakTestCount (0),
+	iFirstLeakIter (0),
+	iMaxFileTestCount (0),
+	iCheckHandles(EFalse)
+	{
+	}
+
+CDstStep::~CDstStep()
+	{
+	delete iActiveWorker;
+	delete iScheduler;
+	}
+
+void CDstStep::PrepareTestEnvironmentL()
+	{
+	// do nothing
+	// sub-classes derive from this to load any script settings they require
+	}
+
+
+TVerdict CDstStep::doTestStepPreambleL()
+	{
+	iScheduler = new CActiveScheduler();
+	CActiveScheduler::Install(iScheduler);
+
+	GetIntFromConfig(ConfigSection(), KRunTestCount, iMaxRunTestCount);
+	GetIntFromConfig(ConfigSection(), KLeakTestCount, iMaxLeakTestCount);
+	GetIntFromConfig(ConfigSection(), KFirstLeakIter, iFirstLeakIter);
+	GetIntFromConfig(ConfigSection(), KFileTestCount, iMaxFileTestCount);
+	GetBoolFromConfig(ConfigSection(), KCheckHandles, iCheckHandles);
+
+	// there must be at least a single normal run;
+	if (iMaxRunTestCount <= 0) iMaxRunTestCount = 1;
+	INFO_PRINTF1(KNormalTestStarted);
+
+	PrepareTestEnvironmentL();
+
+	SetTestStepResult(EPass);
+	return TestStepResult();
+	}
+
+TVerdict CDstStep::doTestStepL()
+	{
+	if(TestStepResult() == EPass)
+		{
+		// the activeWorker is responsible for starting the actual test
+		// from its RunL
+		iActiveWorker = CDSTActiveWorker::NewL(*this);
+		CActiveScheduler::Start();
+
+		delete iActiveWorker;
+		iActiveWorker = NULL;
+		}
+
+	return TestStepResult();
+	}
+
+
+TVerdict CDstStep::doTestStepPostambleL()
+	{
+	delete iScheduler;
+	iScheduler=NULL;
+	CActiveScheduler::Install(NULL);
+
+	return TestStepResult();
+	}
+
+
+void CDstStep::SetFileSession(RFs& aFs)
+	{
+	if (ERunningFileTest == iState)
+		{
+		iFs = &aFs;
+
+		// set handles to allow
+		iFs->SetErrorCondition(KErrTestFileHandle, iTestCount);
+		}
+	}
+
+ 
+void CDstStep::TestCompleted(TInt aCondition)
+	{
+
+	iTestCmd = EDestroyUnit;
+
+	iTestCondition = aCondition;
+	iFs = NULL;
+
+	// Puts the test clean-up into our own active object RunL.
+	// we don't want to delete the test unit in a call from its own RunL or
+	// that of its delegates
+	iActiveWorker->Start();
+
+	}
+
+
+TInt CDstStep::FinishTest()
+	{
+
+	TRAPD(error, DestroyTestUnit());
+	UNUSED_VAR(error); //Used to supress build warnings
+
+	++iTestCount;
+
+	switch (iState)
+		{
+	case ERunningNormalTest:
+		if (iTestCount == iMaxRunTestCount)
+			{
+			TInt endPHandleCount;
+			TInt endTHandleCount;
+			RThread().HandleCount(endPHandleCount, endTHandleCount);
+
+			_LIT(KThreadHandleLeaks, "This test leaked %d thread handles");
+			_LIT(KThreadHandlesLeakCheck, "Thread Handle Leak Check");
+
+			// we cannot test process handles because other threads may be
+			// running in the server
+
+			if (endTHandleCount != iStartTHandleCount)
+				{
+				// TODO: check if EFF_PRINTF2 is better
+				INFO_PRINTF2(KThreadHandleLeaks, endTHandleCount - iStartTHandleCount);
+				}
+
+			if (iCheckHandles)
+				{
+				LogCheck(KThreadHandlesLeakCheck(), 
+					(endTHandleCount == iStartTHandleCount) ? KErrNone : KErrBadHandle);
+				}
+
+			INFO_PRINTF2(KNormalTestComplete, iTestCount);
+
+			iTestCount = 0;
+			if (iMaxLeakTestCount)
+				{
+				iState = ERunningLeakTest;
+				INFO_PRINTF1(KOOMTestStarted);
+				}
+			else if (iMaxFileTestCount)
+				{
+				iState = ERunningFileTest;
+				INFO_PRINTF1(KOOFTestStarted);
+				}
+			else
+				{
+				iState = EIdle;
+				}
+			}
+		break;
+
+	case ERunningLeakTest:
+		__UHEAP_MARKEND;
+		User::Heap().Check();
+		__UHEAP_RESET;
+
+		if ((iTestCondition != KErrNoMemory) || (iTestCount == iMaxLeakTestCount ))
+			{
+
+			INFO_PRINTF2(KOOMTestTerminated, iTestCount);
+			iTestCount = 0;
+			// TODO: save memory leak test result
+
+			// out of memory test completed
+			if (iMaxFileTestCount)
+				{
+				iState = ERunningFileTest;
+				INFO_PRINTF1(KOOFTestStarted);
+				}
+			else
+				{
+				iState = EIdle;
+				}
+			}
+
+		break;
+
+	case ERunningFileTest:
+		if (!iFs)
+			{
+			// no file session object was provided, stop the file test
+			INFO_PRINTF1(KOOFTestAborted);
+			iTestCount = 0;
+			// TODO: save file handle leak test result
+
+			iState = EIdle;
+
+			// _LIT(KFileTestTerm, "Out Of File Handles test terminated: No file session provided");
+			// Utils().LogIt(KFileTestTerm);
+			}
+		else
+			{
+			// clean-up file session handles restriction
+			iFs->SetErrorCondition(KErrNone);
+
+			if ((iTestCondition != KErrTestFileHandle) || (iTestCount == iMaxFileTestCount))
+				{
+				// out of file handle test completed
+				INFO_PRINTF2(KOOFTestTerminated, iTestCount);
+				iTestCount = 0;
+
+				// TODO: save file handle leak test result
+				iState = EIdle;
+
+				}
+			}
+		break;
+
+	default:
+		break;
+		}
+
+	// prepare for the next test state
+	iTestCmd = ECreateUnit;
+
+	iActiveWorker->Start();
+	return iTestCondition;
+	}
+
+
+TInt CDstStep::StartTest()
+	{
+	RThread().HandleCount(iStartPHandleCount, iStartTHandleCount);
+	SetTestStepResult(EFail);
+	TInt results = KErrNone;
+	switch (iState)
+		{
+		case ERunningLeakTest:
+			__UHEAP_MARK;
+			__UHEAP_FAILNEXT(iTestCount);
+		case ERunningFileTest:
+		case ERunningNormalTest:
+			TRAPD(error, results = CreateAndRunTestUnitL());
+			if ((results != KRequestPending) || (error != KErrNone))
+				{
+				// TODO: if there is a leave; log a message to that effect
+				// Test is Synchronous, or leave condition
+				if (results == KErrNone)
+					{
+					results = error;
+					}
+				TestCompleted(results);
+				}
+			break;
+
+		default:
+			// stop the scheduler
+			// All test states covered
+
+			SetTestStepResult(((iTestCondition == KErrNone) && (iChecksFailed == 0)) ? EPass : EFail);
+			CActiveScheduler::Stop();
+			break;
+		}
+
+	return (results);
+	}
+
+
+TInt CDstStep::RunTest()
+	{
+	TInt results = KErrNone;
+
+	switch (iTestCmd)
+		{
+		case ECreateUnit:
+			results = StartTest();
+			break;
+
+		case EDestroyUnit:
+			results = FinishTest();
+			break;
+
+		default:
+			// stop the scheduler
+			// something bad has happened
+			// TODO: Panic
+			SetTestStepResult(EFail);
+			CActiveScheduler::Stop();
+			break;
+		}
+
+	return (results);
+	}
+
+
+void CDstStep::LogCheck(const TDesC& aDescription, TInt aCondition)
+	{
+
+	// set the result for the temporary benefit of any dependent test step
+	// it will be overwritten when the test completes
+	if (aCondition == KErrNone)
+		{
+		SetTestStepResult(EPass);
+		++iChecksPassed;
+		}
+	else
+		{
+		SetTestStepResult(EFail);
+		++iChecksFailed;
+		if (iState == ERunningNormalTest)
+			{
+			// only do the logging in normal test mode.
+			// we don't want to use any resources that interferes with stress testing
+			ERR_PRINTF3(_L("Check: %S: Error Code: %d"), &aDescription, aCondition);
+			}
+		}
+	}
+
+
+TTime CDstStep::ReadTimeParamStringL(const TDesC& aParamString)
+	{
+	// Format of buffer to construct a TTime is YYYYMMDD:HHMMSS (15 characters).
+	// TTime uses zero-based values for month and day - which is confusing for scripting.
+	// In our script, we use actual month and day numbers to make things simpler so we
+	// must modify the string here to take account of this.
+	TBuf<32> buf;
+	TInt m, d;
+
+	buf.Zero();
+	buf.Copy(aParamString.Left(4));		// The year
+	TLex lexMonth = aParamString.Mid(4, 2);
+	lexMonth.Val(m);
+	TLex lexDay = aParamString.Mid(6, 2);
+	lexDay.Val(d);
+	buf.AppendFormat(_L("%02d%02d"), m - 1, d - 1);	// The month and day
+	buf.Append(aParamString.Right(7));
+
+	return TTime(buf);
+	}