--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/t_utils/HttpTestCore.cpp Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,510 @@
+// Copyright (c) 2001-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 "HttpTestCore.h"
+
+_LIT(KTextFailure,"Test failed with error %d.\n");
+_LIT(KTextFailedTest,"TEST %S FAILED\n");
+_LIT(KTextPassedTest,"TEST %S PASSED\n");
+_LIT(KTextInterruptTest, "TEST %S INTERRUPTED\n");
+
+// Dummy POST body provided in test base should a specific test not want to generate its own
+_LIT8(KTestPostBody, "a=10\r\n");
+
+// format for output of data/time values
+_LIT(KDateFormat,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S.%C%:3");
+
+
+// Test harness requirements:
+// Uses an active object state machine to run tests.
+
+
+//##ModelId=3A76DDA701A2
+EXPORT_C void CTestScheduler::Error(TInt anError) const
+ {
+ _LIT(KTestPanic,"CTestScheduler RunL leave");
+ User::Panic(KTestPanic,anError);
+ }
+
+// CHttpTestEngine
+
+EXPORT_C void CHttpTestEngine::SetCurrentStatusCode(TInt aStatusCode)
+ {
+ iCurrentStatusCode=aStatusCode;
+ }
+
+
+void CHttpTestEngine::DoCancel()
+ {
+ // cancel the current test
+ if (iCurrentTest)
+ iCurrentTest->Cancel();
+ }
+
+void CHttpTestEngine::RunL()
+ {
+ switch (iState)
+ {
+ case EIdle:
+ {
+ TRAPD(err,RunNextTestL())
+ if (err!=KErrNone)
+ {
+ Console().Printf(KTextFailure, err);
+ }
+ }
+ break;
+ case ERunningTest:
+ case ESingleTestCaseFailed:
+ break;
+ case EShuttingDown:
+ CActiveScheduler::Stop();
+ break;
+ }
+ }
+
+
+EXPORT_C void CHttpTestEngine::PressAnyKey()
+ {
+ if (iDetectKeyPress)
+ iDetectKeyPress->Cancel();
+
+ iUtils->PressAnyKey();
+
+ if (iDetectKeyPress)
+ iDetectKeyPress->RequestKey();
+
+ }
+
+void CHttpTestEngine::TestInteractionDetectedL(TTestInteraction aTestInteraction)
+ {
+ if (aTestInteraction == EStopCurrentTest)
+ {
+ iCurrentTest->Cancel();
+ TestCompleted(KErrTestInterrupted);
+ }
+ }
+
+
+/**
+ * Static factory function for a new test engine
+ */
+EXPORT_C CHttpTestEngine* CHttpTestEngine::NewL(const TDesC& aTestTitle, TBool aSilent)
+ {
+ CHttpTestEngine* self = new(ELeave) CHttpTestEngine(aSilent);
+ CleanupStack::PushL(self);
+ self->ConstructL(aTestTitle);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CHttpTestEngine::CHttpTestEngine(TBool aSilent)
+ : CActive(CActive::EPriorityUserInput), iSilent(aSilent)
+ {
+ }
+
+/**
+ * Constructor for the test engine
+ * Creates a console and sets itself active
+ */
+void CHttpTestEngine::ConstructL(const TDesC& aTestTitle)
+ {
+ iUtils = CHTTPTestUtils::NewL(aTestTitle);
+ iUtils->SetSilent(iSilent);
+ iDetectKeyPress = CDetectKeyPress::NewLC(*(iUtils->Test().Console()),*this);
+ CleanupStack::Pop(iDetectKeyPress);
+ CActiveScheduler::Add(this);
+ SetActive();
+ TRequestStatus* stat = &iStatus;
+ User::RequestComplete(stat,KErrNone);
+ }
+
+/**
+ * Destructor for CHttpTestEngine
+ * Cancels any outstanding requests and deletes member variables
+ */
+EXPORT_C CHttpTestEngine::~CHttpTestEngine()
+ {
+ Cancel();
+ iTestSet.Close();
+ iTestResults.Close();
+ delete iDetectKeyPress;
+ delete iUtils;
+ }
+
+/**
+ * Configure the set of tests to be done in this run of the test engine.
+ */
+EXPORT_C void CHttpTestEngine::ConfigureTestSet(RPointerArray<CHttpTestBase> aTestSet)
+ {
+ iTestSet = aTestSet;
+ }
+
+/**
+ * This should be called by tests to indicate that they have
+ * completed and whether they were sucessful or not
+ */
+EXPORT_C void CHttpTestEngine::TestCompleted(TInt aResult)
+ {
+ // Log test result. Override silence to ensure something gets displayed
+ TBool wasSilent = iUtils->IsSilent();
+ iUtils->SetSilent(EFalse);
+ // An expected status code of 0 is used if the test doesn't care about a status code to pass
+ if (aResult == 0)
+ {
+ iUtils->LogIt(KTextPassedTest, &(iCurrentTest->TestName()));
+ iTestResults.Append(ETrue);
+ }
+ else if (aResult == KErrTestInterrupted)
+ {
+ iUtils->LogIt(KTextInterruptTest, &(iCurrentTest->TestName()));
+ iTestResults.Append(EFalse);
+ }
+ else
+ {
+ iUtils->LogIt(KTextFailedTest, &(iCurrentTest->TestName()));
+ iTestResults.Append(EFalse);
+ }
+ iUtils->SetSilent(wasSilent);
+
+ // Inform test utils that this test is over
+ iUtils->EndTest(aResult);
+
+ // Switch state so the engine can point at the next test, then set the engine active again
+ iState=EIdle;
+ TRequestStatus* stat = &iStatus;
+ User::RequestComplete(stat,KErrNone);
+ SetActive();
+ }
+
+
+/**
+ * Run the next test
+ * The switch statement lists all tests to be run
+ *
+ */
+void CHttpTestEngine::RunNextTestL()
+ {
+ // delete the test previously run
+
+ delete iCurrentTest;
+ iCurrentTest=NULL;
+
+ // Advance to the next test
+
+ iTestIndex++;
+ if (iTestIndex <= iTestSet.Count())
+ {
+ // still going...
+ iCurrentTest = iTestSet[iTestIndex - 1];
+ iCurrentTest->SetEngine(this);
+ iUtils->StartTestL(iCurrentTest->TestName());
+ iState = ERunningTest;
+ iCurrentTest->BeginTest();
+ }
+ else
+ {
+ // finished testing - set status to shut down and complete our own request
+ SetPriority(EPriorityIdle);
+ iState = EShuttingDown;
+ int a,b;
+ TestSummary(a,b);
+ TRequestStatus* stat = &iStatus;
+ User::RequestComplete(stat,KErrNone);
+ SetActive();
+ return;
+ }
+ }
+
+/**
+ * return a reference to the console used by the test harness
+ */
+EXPORT_C CConsoleBase& CHttpTestEngine::Console() const
+ {
+ return *(iUtils->Test().Console());
+ }
+
+/**
+ * return a reference to the test harness utilities
+ */
+EXPORT_C CHTTPTestUtils& CHttpTestEngine::Utils() const
+ {
+ return *iUtils;
+ }
+
+
+EXPORT_C void CHttpTestEngine::TestSummary(TInt& aNumPasses, TInt& aNumFailures) const
+ {
+ aNumPasses = 0;
+ aNumFailures = 0;
+ for (TInt ii = 0; ii < iTestResults.Count(); ii++)
+ iTestResults[ii]?(aNumPasses++):(aNumFailures++);
+ }
+
+
+//-----CHttpTestBase------------------------------------------------------------------
+
+EXPORT_C CHttpTestBase::CHttpTestBase() : CActive(CActive::EPriorityStandard)
+ {
+ iExpectedStatusCode= 200;
+ iTestFail=0;
+ }
+
+EXPORT_C TInt CHttpTestBase::ExpectedStatusCode()
+ {
+ return iExpectedStatusCode;
+ }
+
+EXPORT_C void CHttpTestBase::BeginTest()
+ {
+ CActiveScheduler::Add(this);
+ SetActive();
+ TRequestStatus* stat = &iStatus;
+ User::RequestComplete(stat,KErrNone);
+ }
+
+EXPORT_C void CHttpTestBase::RunL()
+ {
+ // Either do leak tests or regular tests
+ TInt err = KErrNone;
+ if (iLeakTests > 0)
+ {
+ TRAP(err,DoLeakTestsL());
+ }
+ else
+ {
+ TRAP(err,DoRunL());
+ }
+
+ switch(err)
+ {
+ case KErrNone:
+ {
+ iEngine->Utils().LogIt(_L("\nTest case finished"));
+ if (!iEngine->IsSilent())
+ iEngine->PressAnyKey();
+ }
+ break;
+ default:// any error
+ {
+ iEngine->Utils().LogIt(_L("Test case failed (caught a Leave) ... skipping to the next test case"));
+ }
+ break;
+ }
+ iEngine->TestCompleted(err);
+ }
+
+
+void CHttpTestBase::DoLeakTestsL()
+ {
+ for (TInt ii = iFirstLeakIteration; ii < iLeakTests; ++ii)
+ {
+ iEngine->Utils().LogIt(_L("Memory Leak Testing on allocation %d\n"), ii);
+
+ TInt err = KErrNoMemory;
+
+ __UHEAP_MARK;
+ __UHEAP_FAILNEXT(ii);
+ TRAP(err,DoRunL());
+ __UHEAP_MARKEND;
+ User::Heap().Check();
+ __UHEAP_RESET;
+
+ // Break out if the test passes successfully; allow only memory failure or test failure codes to proceed.
+ if (err == KErrNone)
+ return;
+ else if (err != KErrNoMemory && err != KErrTestFailed)
+ User::Leave(err);
+ }
+ }
+
+EXPORT_C TInt CHttpTestBase::RunError(TInt aErr)
+ {
+ iEngine->Utils().LogIt(_L("\nTest failed with error code %d\n"), aErr);
+ return KErrNone;
+ }
+
+EXPORT_C void CHttpTestBase::CompleteOwnRequest()
+ {
+ TRequestStatus* stat = &iStatus;
+ User::RequestComplete(stat,KErrNone);
+ if (!IsActive())
+ SetActive();
+ }
+
+
+//-----CHttpTestTransBase------------------------------------------------------------------
+
+EXPORT_C CHttpTestTransBase::CHttpTestTransBase() : CHttpTestBase()
+ {
+ }
+
+EXPORT_C TBool CHttpTestTransBase::GetNextDataPart(TPtrC8& aDataChunk)
+ {
+ //add a body
+ aDataChunk.Set(KTestPostBody);
+ return ETrue;
+ }
+
+EXPORT_C void CHttpTestTransBase::ReleaseData()
+ {
+ }
+
+EXPORT_C TInt CHttpTestTransBase::OverallDataSize()
+ {
+ return KTestPostBody().Length();
+ }
+
+EXPORT_C void CHttpTestTransBase::DumpResponseBody(RHTTPTransaction& aTrans)
+//dump all the body's chunks
+ {
+ MHTTPDataSupplier* body = aTrans.Response().Body();
+ TPtrC8 dataChunk;
+ TBool isLast = body->GetNextDataPart(dataChunk);
+ iEngine->Utils().DumpData(dataChunk);
+ if (isLast && !iEngine->IsSilent())
+ iEngine->Utils().LogIt(_L("Got last data chunk.\n"));
+ body->ReleaseData();
+ }
+
+EXPORT_C void CHttpTestTransBase::DumpRespHeaders(RHTTPTransaction& aTrans)
+//dump the message's headers
+ {
+ //dump the message's headers
+ RHTTPResponse resp = aTrans.Response();
+ TInt status = resp.StatusCode();
+ if (!iEngine->IsSilent())
+ iEngine->Utils().LogIt(_L("Status code = %d\n"), status);
+
+ RStringPool strP = aTrans.Session().StringPool();
+ RHTTPHeaders hdr = resp.GetHeaderCollection();
+ THTTPHdrFieldIter it = hdr.Fields();
+
+ TBuf<32> fieldName16;
+ TBuf<128> fieldVal16;
+
+ while (it.AtEnd() == EFalse)
+ {
+ RStringTokenF fieldNameTk = it();
+ RStringF fieldName = strP.StringF(fieldNameTk);
+ THTTPHdrVal hVal;
+ if (hdr.GetField(fieldName,0,hVal) == KErrNone)
+ {
+ TPtrC8 fieldNameStr(strP.StringF(fieldName).DesC());
+ if (fieldNameStr.Length() > 32)
+ fieldNameStr.Set(fieldNameStr.Left(32));
+
+ fieldName16.Copy(fieldNameStr);
+
+ THTTPHdrVal fieldVal;
+ hdr.GetField(fieldName,0,fieldVal);
+ switch (fieldVal.Type())
+ {
+ case THTTPHdrVal::KTIntVal:
+ {
+ iEngine->Utils().LogIt(_L("%S: %d\n"), &fieldName16, fieldVal.Int());
+ } break;
+ case THTTPHdrVal::KStrVal:
+ case THTTPHdrVal::KStrFVal:
+ {
+ TPtrC8 fieldValStr(strP.StringF(fieldVal.StrF()).DesC());
+ if (fieldValStr.Length() > 128)
+ fieldValStr.Set(fieldValStr.Left(128));
+
+ fieldVal16.Copy(fieldValStr);
+ iEngine->Utils().LogIt(_L("%S: %S\n"), &fieldName16, &fieldVal16);
+ } break;
+ case THTTPHdrVal::KDateVal:
+ {
+ TDateTime date = fieldVal.DateTime();
+ TTime t(date);
+ TBuf<128> dateTimeString;
+ TRAPD(err,t.FormatL(dateTimeString,KDateFormat));
+ if (err == KErrNone)
+ iEngine->Utils().LogIt(_L("%S: %S\n"), &fieldName16, &dateTimeString);
+ } break;
+ default:
+ {
+ iEngine->Utils().LogIt(_L("%S: <unrecognised value type>\n"), &fieldName16);
+ }
+ }
+ }
+ ++it;
+ }
+ }
+
+EXPORT_C TInt CHttpTestTransBase::MHFRunError(TInt aError,
+ RHTTPTransaction /*aTransaction*/,
+ const THTTPEvent& /*aEvent*/)
+ {
+ iEngine->Utils().LogIt(_L("\nTest failed with error code %d\n"), aError);
+ return KErrNone;
+ }
+
+EXPORT_C void CHttpTestTransBase::MHFRunL(RHTTPTransaction aTransaction,
+ const THTTPEvent& aEvent)
+ {
+ switch (aEvent.iStatus)
+ {
+ case THTTPEvent::EGotResponseHeaders:
+ {
+ // HTTP response headers have been received
+ iEngine->Utils().LogIt(_L("<EGotResponseHeaders>\n"));
+ DumpRespHeaders(aTransaction);
+ iEngine->SetCurrentStatusCode(aTransaction.Response().StatusCode());
+ } break;
+ case THTTPEvent::EGotResponseBodyData:
+ {
+ // Some (more) body data has been received (in the HTTP response)
+ iEngine->Utils().LogIt(_L("<EGotResponseBodyData received>\n"));
+ // for each chunk of data received we have to empty the buffer before to be able to receive
+ MHTTPDataSupplier* body = aTransaction.Response().Body();
+ body->ReleaseData();
+ } break;
+ case THTTPEvent::EResponseComplete:
+ {
+ // The transaction's response is complete
+ iEngine->Utils().LogIt(_L("<EResponseComplete received >\n"));
+ } break;
+ case THTTPEvent::ESucceeded:
+ {
+ iEngine->Utils().LogIt(_L("<ESucceeded received from the VF>\n"));
+ CActiveScheduler::Stop();
+ } break;
+ case THTTPEvent::EFailed:
+ {
+ iEngine->Utils().LogIt(_L("<EFailed received from the VF>\n"));
+ CActiveScheduler::Stop();
+ } break;
+ default:
+ {
+ iEngine->Utils().LogIt(_L("<unrecognised event>\n %d"),aEvent.iStatus);
+ iEngine->Utils().LogIt(_L("Test Failed\n"));
+ iEngine->PressAnyKey();
+ CActiveScheduler::Stop();
+ }
+ break;
+ }
+ }
+
+EXPORT_C void CHttpTestEngine::SetSilent(TBool aSilent)
+ {
+ iUtils->SetSilent(aSilent);
+ }
+
+EXPORT_C TInt CHttpTestTransBase::Reset()
+ {
+ return KErrNone;
+ }