diff -r 9f5ae1728557 -r db3f5fa34ec7 messagingfw/wappushfw/tpush/t_wappush.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingfw/wappushfw/tpush/t_wappush.cpp Wed Nov 03 22:41:46 2010 +0530 @@ -0,0 +1,762 @@ +// Copyright (c) 2000-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 +#include // for RDebug::Print +#include +#include +#include "t_wappush.h" +#include "pushtests.h" +#include +#include + +// service setup includes... +#include +#include +#include "t_serviceutils.h" +#include + +#include "cwappushfailmessagetest.h" + +_LIT(KPushMtmDatFile, "z:\\system\\mtm\\WapPushMtmU.dat"); +_LIT(KWapPushTestTitle,"WAP Push tests"); +_LIT(KPushLogDir, "push"); +_LIT(KPushLogFile, "WapPushLogging.txt"); +_LIT(KSpace, " "); +_LIT(KStartTest,"Test Results"); +_LIT(KFinishedTest,"Tests Completed"); +_LIT(KTestDirectory,"C:\\Logs\\push\\"); +_LIT(KTest,"> TEST "); +_LIT(KPassed," PASSED\n"); +_LIT(KFailed," Failed\n RTEST: FAIL :"); // RTEST: FAIL : required for the DABS RTest result parser to work +_LIT (KOOMTestStep, "OOM Test step at %d\n" ); + +LOCAL_D RTest test( KWapPushTestTitle ); + +// Test harness requirements +// +// Uses an active object state machine to run tests. +// Creates a Connection Manager object. +// Creates a Dummy wap stack via CDummyWapStack::NewL() +// Feeds a push message to Dummy wap stack +// Starts Connection Manager - just add active object to scheduler and start? +// Needs to know when completed - and callback? +// Verifies that CPushMessage received is the same as sent +// Closes/Destroys connection manager - delete? +// + +// Note : +// -To run the test harness on hardware, build the ROM image using +// TWappush.iby file in \Wap-Browser\WapPush\rom\.. directory. +// -Build the Wappush component and the TWappush test harness for DEBUG mode +// -Create a folder c:\logs\push\.. to get the WappushLogging.txt logfile. +// + +class CTestScheduler : public CActiveScheduler + { + virtual void Error(TInt anError) const; + }; + +void CTestScheduler::Error(TInt anError) const + { + TBuf<80> buf; + + _LIT(KComment, "!! Error - %d\n-> Test Scheduler error handler called"); + buf.Format(KComment, anError); + + // Write to log file + RFileLogger::Write(KPushLogDir, KPushLogFile, EFileLoggingModeAppend, buf); + + _LIT(KTestPanic,"CTestScheduler RunL leave"); + User::Panic(KTestPanic,anError); + } + + + + +// cwappushtestengine + +void CWapPushTestEngine::DoCancel() + { + // cancel the current test + if (iCurrentTest) + iCurrentTest->Cancel(); + } + +void CWapPushTestEngine::RunL() + { + switch (iState) + { + case EIdle: + { + if(iTest!=EFinished) + { + test.Start(_L("Starting Unit Test")); + } + TRAPD(err,RunNextTestL()) + if(iTest!=EFinished) + { + test.End(); + test.Close(); + } + if (err!=KErrNone) + iConsole->Printf(KTextFailedTest); + } + break; + case ERunningTest: + break; + case EShuttingDown: + // Clear Out the Plugin Cache +// CPluginServerClient* psc = CPluginServerClient::NewL(); +// psc->PluginFactory().ClearCache(); +// delete psc; + CActiveScheduler::Stop(); + break; + } + } + +/** + * Static factory function for a new test engine + */ +CWapPushTestEngine* CWapPushTestEngine::NewL() + { + CWapPushTestEngine* self = new(ELeave) CWapPushTestEngine(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** + * Constructor for the test engine + * Creates a console and sets itself active + */ +void CWapPushTestEngine::ConstructL() + { + // Write to log file + RFileLogger::Write(KPushLogDir, KPushLogFile, EFileLoggingModeAppend, KStartTest); + RFileLogger::Write(KPushLogDir, KPushLogFile, EFileLoggingModeAppend, KSpace); + + iConsole = Console::NewL(KWapPushTestTitle,TSize(KConsFullScreen,KConsFullScreen)); + // set up service BEFORE active scheduler... + InitialiseMsgServiceL(); + // + CActiveScheduler::Add(this); + SetActive(); + TRequestStatus* stat = &iStatus; + User::RequestComplete(stat,KErrNone); + } + +/** + * Destructor for CWapPushTestEngine + * Cancels any outstanding requests and deletes member variables + */ +CWapPushTestEngine::~CWapPushTestEngine() + { + Cancel(); + delete iCurrentTest; + delete iConsole; + } + +/** + * This should be called by tests to indicate that they have + * completed and whether they were sucessful or not + */ +void CWapPushTestEngine::TestCompleted(TInt aResult) + { + if (aResult==KErrNone) + { + TBuf16<124> log; + log = iCurrentTest->TestName(); + log.Append(KTest); + log.Append(iCurrentTest->TestName()); + log.Append(KPassed); + test.Printf(log); + iState=EIdle; + iTest=(TTest)(iTest+1); + } + else + { + TBuf16<124> log1; + log1 = iCurrentTest->TestName(); + log1.Append(KTest); + log1.Append(iCurrentTest->TestName()); + log1.Append(KFailed); + test.Printf(log1); + test.Printf(KTextFailedTest); + iConsole->Printf(KTextFailedTest); + iState = EShuttingDown; + } + // set active again + TRequestStatus* stat = &iStatus; + User::RequestComplete(stat,KErrNone); + SetActive(); + } + +/** + * Run the next test + * The switch statement lists all tests to be run + * + */ +void CWapPushTestEngine::RunNextTestL() + { + // delete any old tests + delete iCurrentTest; + iCurrentTest=NULL; + // + + switch (iTest) + { + case EFailMessageTest: + test.Next( _L("Test - Failing Messages (were causing panics) started")); + iCurrentTest = new (ELeave)CWapPushFailMessageTest(); + break; + case ESIAMessage: + test.Next( _L("Test - Service Intiation Application started")); + iCurrentTest = new (ELeave) CWapPushSIAMessageTest(); + break; + case EUnknownMessage: + test.Next( _L("Test - Unknown Handler Test started")); + iCurrentTest = new (ELeave) CWapPushUnkMessageTest(); + break; + case ESLMessage: + test.Next( _L("Test - Service Loading started")); + iCurrentTest = new (ELeave) CWapPushSLMessageTest(); + break; + case ESLCMessage: + test.Next (_L("Test - Service Loading Content started") ); + iCurrentTest = new ( ELeave )CWapPushSLCMessageTest(); + break; + case ESIMessage: + test.Next( _L("Test - Service Indication started")); + iCurrentTest = new (ELeave) CWapPushSIMessageTest(); + break; + case ESICMessage: + test.Next( _L("Test - Service Indication Content started")); + iCurrentTest = new (ELeave) CWapPushSICMessageTest(); + break; + case EMultipartMixed: + test.Next( _L("Test - Multi-part Mixed Message Test started")); + iCurrentTest = new (ELeave) CWapPushMMMessageTest(); + break; + case EMultipartRelated: + test.Next( _L("Test - Multi-part Related Message Test started")); + iCurrentTest = new (ELeave) CWapPushMRMessageTest(); + break; + case EMultipartAlternative: + test.Next( _L("Test - Multi-part Alternative Message Test started")); + iCurrentTest = new (ELeave) CWapPushMAMessageTest(); + break; + case EReleaseThree: + test.Next( _L("Test - Release Three started")); + iCurrentTest = new (ELeave) CWapPushR3Test(); + break; + case ECorruptMsgs: + test.Next( _L("Test - Corrupt Message Test started")); + iCurrentTest = new (ELeave) CWapPushCorruptMessageTest(); + break; + case EClientMtmFind: + test.Next( _L("Test - WapPushClientMtm Find Test started")); + iCurrentTest = new (ELeave) CWapClientMtmFindTest(); + break; + case EINC081489: + test.Next( _L("Duplicate SI messages [CINC081489]")); + iCurrentTest = new (ELeave) CINC081489(); + break; + case EInvalidDTDMessage: + test.Next ( _L("Invalid WAP DTD Message Test") ); + iCurrentTest = new ( ELeave) CInvalidWAPDTDMessages(); + break; + case EDRMMessage: + test.Next( _L("Test - DRM started")); + iCurrentTest = new (ELeave) CWapPushDRMMessageTest(); + break; + case EReleaseTwo: + default: + // We've finished - set status to shut down and complete our own request + SetPriority(EPriorityIdle); + + // Write to log file + RFileLogger::Write(KPushLogDir, KPushLogFile, EFileLoggingModeAppend, KSpace); + RFileLogger::Write(KPushLogDir, KPushLogFile, EFileLoggingModeAppend, KFinishedTest); + + iConsole->Printf(KTextFinishedTest); + iState = EShuttingDown; + TRequestStatus* stat = &iStatus; + User::RequestComplete(stat,KErrNone); + SetActive(); + return; + } + + iCurrentTest->SetEngine(this); + iState = ERunningTest; + iCurrentTest->BeginTest(); + } + + /** + * print a descriptor to the console - prefixes aString text with aName + * @param aName the name of the test + * @param aString the text to be displays + */ +void CWapPushTestEngine::Printf(const TDesC& aName, const TDesC& aString) + { + TBuf<12> format; + format.Zero(); + format.AppendNum((TInt)iTest); + _LIT(KTextCoreFormat,".%S: %S\n"); + format.Append(KTextCoreFormat); + iConsole->Printf(format,&aName,&aString); + } + +/** + * get a character from the console + */ +TKeyCode CWapPushTestEngine::Getch() + { + return iConsole->Getch(); + } + +/** + * return a reference to the console used by the test harness + */ +CConsoleBase& CWapPushTestEngine::Console() const + { + return *iConsole; + } + +/** connect to the push message service + + if no message service set up then create one else + use existing service and remove any existing messages +*/ +void CWapPushTestEngine::InitialiseMsgServiceL() + { + CMsvEntrySelection* idArray = new (ELeave) CMsvEntrySelection(); + CleanupStack::PushL(idArray); + + CWapPushTestMsgUtils* msgUtils = CWapPushTestMsgUtils::NewL(); + CleanupStack::PushL(msgUtils); + TMsvId pushService = KMsvNullIndexEntryId; + TMsvId pushFolder = KMsvNullIndexEntryId; + + // uncomment this if you want to remove existing service entries + //msgUtils->ClearExistingServiceEntriesL(KUidMtmWapPush); + + msgUtils->PushServiceIdL(pushService, idArray); + if ((pushService == KMsvNullIndexEntryId) && (idArray->Count() ==0) ) // Found no service + { + pushService = msgUtils->CreateServiceL(); + } + // install mtm - leaves if found to already exist + TRAP_IGNORE(msgUtils->InstallMtmGroupL(KPushMtmDatFile)); + + + idArray->Reset(); + msgUtils->PushFolderIdL(pushFolder, idArray); + + if ((pushFolder == KMsvNullIndexEntryId) && (idArray->Count() ==0) ) // Found no service + pushFolder = msgUtils->CreatePushMsgFolderL(); + + + //Clean out all previous push entries from under the Push Service Entry + msgUtils->RemoveServiceEntryChildrenL(pushService); + + // Clean the push msg folder of existing entries + msgUtils->RemoveEntriesFromLocalServiceFolderL(pushFolder, KUidMtmWapPush); + // Clean the inbox of all existing Wap Push entries.... + msgUtils->RemoveEntriesFromLocalServiceFolderL(KMsvGlobalInBoxIndexEntryId, KUidMtmWapPush); + + CleanupStack::PopAndDestroy(2); //idarray, msgUtils + } + + + +/** Add the test to the active scheduler and set it active + * by completing its own request + */ +void CWapPushTest::BeginTest() + { + CActiveScheduler::Add(this); + SetActive(); + TRequestStatus* stat = &iStatus; + User::RequestComplete(stat,KErrNone); + } + + +/** + * Print a descriptor to the console + * @param aString descriptor to print + */ +void CWapPushTest::Printf(const TDesC& aString) + { + iEngine->Printf(TestName(),aString); + } + +/** + * Check a test result and panic if false + * @param aTestResult the result to check + * @param aLine the line number - can be provided by MSVC macro __LINE__ + * #define TEST(A) Test(A,__LINE__) + * TEST(err=KErrNone) + */ +void CWapPushTest::Test(TInt aTestResult,TInt aLine) + { + if (!aTestResult) + { + User::Panic(TestName(),aLine); + } + } + +/** +* Printf +* +* @param aDescription The text to print/log +*/ +void CWapPushTest::WPLPrintf(const TDesC& aDescription) + { + const TInt KWatcherLogBuffer = 256; + // Write to log file + RFileLogger::Write(KPushLogDir, KPushLogFile, EFileLoggingModeAppend, aDescription); + + // Write to console + _LIT(KPushLogFmt,"Push:%S\n"); + TPtrC buf = aDescription.Left(Min(KWatcherLogBuffer, aDescription.Length())); + iEngine->Console().Printf(KPushLogFmt,&buf); + } + +/** + * Takes the data in a Push Message and prints it to console and the logs it to file. + * Uses the accessor functions of the CPushMessage class and this classes Printf function + * to perform this. Currently 4 headers and the message body are displayed and + * logged. The headers are: + * PushID, Content-Type, X-Application-ID, Expiry Date, + * + * @param CPushMessage& aMessage + * in: a reference to a Push Message. + */ +void CWapPushTest::WPLPrintfL(CPushMessage& aMessage) + { + const TInt KWatcherLogBuffer=256; + TBuf buf; + + // Content type + _LIT(KLogContentFmt,"Content Type : \t%S"); + TPtrC contentPointer; + aMessage.GetContentType(contentPointer); + buf.Format(KLogContentFmt,&contentPointer); + buf.Append('\n'); + WPLPrintf(buf); + + // Date Field + _LIT(KLogDateTimeFmt," %-B%:0%J%:1%T%:2%S%+B %D %N %Y %4 %5 %3"); + _LIT(KLogDateFmt,"Date :\t%S"); + TBool foundField; + TTime timeValue; + foundField = aMessage.GetHeaderField(EHttpDate, timeValue); + if (foundField) + { + TRAPD(err, timeValue.FormatL(buf, KLogDateTimeFmt)); + if (err == KErrNone) + { + TBuf dateBuf; + dateBuf.Format(KLogDateFmt, &buf); + WPLPrintf(dateBuf); + } + } + + //Expires Field + aMessage.GetHeaderField(EHttpExpires, timeValue); + if (foundField) + { + TRAPD(err, timeValue.FormatL(buf, KLogDateTimeFmt)); + if (err == KErrNone) + { + TBuf dateBuf; + dateBuf.Format(KLogDateFmt, &buf); + WPLPrintf(dateBuf); + } + } + + // X-Wap-Application-ID + TBool isInt = EFalse; + TInt ID = 0; + TPtrC8 generalPtr; + _LIT(KLogAppIdIntFmt,"App ID :\t%X"); + TRAPD(err, foundField = aMessage.GetAppIdL(generalPtr, ID, isInt)); + if ( err == KErrNone && foundField) // App ID is present + { + if (isInt) // Field in integer format + { + buf.Format(KLogAppIdIntFmt,ID); + } + else // should be descriptor format + { + buf.Copy(generalPtr); + } + WPLPrintf(buf); + } + + // Content-Disposition + TPtrC8 dispositionPtr; + _LIT(KLogDisposition,"Content-Disposition:\t"); + foundField = aMessage.GetHeaderField(EHttpContentDisposition, dispositionPtr); + if (foundField) // App ID is present + { + // Convert 8 bit to 16 bit + HBufC* tempAddr = HBufC::NewLC(dispositionPtr.Length()); + tempAddr->Des().Copy(dispositionPtr); + WPLPrintf(KLogDisposition); + WPLPrintf(*tempAddr); + CleanupStack::PopAndDestroy(tempAddr); + } + + //Message Header Binary + _LIT(KLogMsgHdr,"Header Binary:"); + WPLPrintf(KLogMsgHdr); + aMessage.GetHeader(generalPtr); + + HBufC* tempHdr = HBufC::NewLC(generalPtr.Length()); + tempHdr->Des().Copy(generalPtr); + WPLLogBinaryAsHex(*tempHdr); + CleanupStack::PopAndDestroy(); //tempHdr + + //Message Body + aMessage.GetMessageBody(generalPtr); + + // Dump Body As Text + _LIT(KLogMsgBody,"Body Text:"); + WPLPrintf(KLogMsgBody); + HBufC* tempBody = HBufC::NewLC(generalPtr.Length()); + tempBody->Des().Copy(generalPtr); + WPLPrintf(*tempBody); + + // Dump Body As Hex + _LIT(KBodyBinary,"\nBody Binary:"); + WPLPrintf(KBodyBinary); + WPLLogBinaryAsHex(*tempBody); + + CleanupStack::PopAndDestroy(); //tempBody + } + + + /** + * Prints out Buffer data in the format: + * %X %X %X %X %X %X %X\n etc + * For example + * AB CD 01 12 34 A2 + * + * @param aDescription + * in: the descriptor to be dumped into the log + */ +void CWapPushTest::WPLLogBinaryAsHex(const TDesC& aDescription) + { + const TInt KWatcherLogBuffer=256; + _LIT(KHexSpace,"%02X "); + TBuf hexBuf; + TBuf buf; + + TInt i = 0, bodyLen = aDescription.Length(); + + for (; i < bodyLen; i++) + { + hexBuf.Format(KHexSpace,aDescription[i]); + buf.Append(hexBuf); + if ( i && ((i+1) % 8) == 0 ) + { + WPLPrintf(buf); + buf.Zero(); + } + } + + if (buf.Length()) + WPLPrintf(buf); + } + +void CWapPushTest::WPLLogError(const TDesC& aDescription,TInt aError) + { + _LIT(KErrorLogFmt,"%S, Error\t%d"); + const TInt KWatcherLogBuffer=256; + TBuf buf; + buf.Format(KErrorLogFmt,&aDescription,aError); + buf.Append('\n'); + WPLPrintf(buf); + } + +CWapPushOOMTestEngine* CWapPushOOMTestEngine::NewL () + { + CWapPushOOMTestEngine* self = new (ELeave)CWapPushOOMTestEngine; + CleanupStack::PushL ( self ); + self->ConstructL (); + CleanupStack::Pop (); + return self; + } + +CWapPushOOMTestEngine::~CWapPushOOMTestEngine () + { + // Do nothing. + } + +void CWapPushOOMTestEngine::TestCompleted ( TInt aResult ) + { + SetError ( aResult ); + if ( aResult == KErrNone ) + { + // The test passed. Increment the test number to next. + iTest=(TTest)(iTest+1); + iState = EIdle; + } + else + { + // Something went wrong shutdown the engine + iState = EShuttingDown; + } + // set active again + TRequestStatus* stat = &iStatus; + User::RequestComplete(stat,KErrNone); + SetActive(); + } + +void CWapPushOOMTestEngine::DoCancel () + { + CWapPushTestEngine::DoCancel (); + } + +CWapPushTestEngine::TTest CWapPushOOMTestEngine::NextTest () const + { + return iTest; + } + +void CWapPushOOMTestEngine::SetNextTest ( TInt aTest ) + { + iTest = (TTest)aTest; + } + +void CWapPushOOMTestEngine::RunL () + { + switch (iState) + { + case CWapPushTestEngine::EIdle: + { + //Skip oom test for ESIMessage. it goes in loop + if(iTest==ESIAMessage || iTest==ESICMessage || iTest==EDRMMessage) + { + iTest=(TTest)(iTest+1); + } + TRAPD( err,RunNextTestL() ); + if ( err != KErrNone ) + TestCompleted ( err ); + } + break; + case CWapPushTestEngine::ERunningTest: + break; + case CWapPushTestEngine::EShuttingDown: + // We are stopping. Stop the active scheduler and exit. + CActiveScheduler::Stop(); + break; + } + } + +TInt CWapPushOOMTestEngine::Error () const + { + return iError; + } + +void CWapPushOOMTestEngine::SetError ( TInt aErr ) + { + iError = aErr; + } + +LOCAL_C void StartOomTestL ( TInt& aNextTest ) + { + CWapPushOOMTestEngine* oomEngine = NULL; + oomEngine = CWapPushOOMTestEngine::NewL(); + CleanupStack::PushL ( oomEngine ); + oomEngine->SetNextTest ( aNextTest ); + // All the action happens within the main event loop + CActiveScheduler::Start(); + aNextTest = (TInt)oomEngine->NextTest (); + User::LeaveIfError ( oomEngine->Error () ); + CleanupStack::PopAndDestroy (); + } + +// main loop +// +GLDEF_C TInt E32Main() + { +__UHEAP_MARK; + + // Install exception handler + CTrapCleanup* theCleanup = CTrapCleanup::New(); + + test.Printf(_L("@SYMTestCaseID IWS-WAPBROWSER-WAPPUSH-TPUSH-T_WAPPUSH-0001 ")); + + // Create test directory + TRAPD( + error, + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + fs.MkDirAll(KTestDirectory); + CleanupStack::PopAndDestroy(&fs); + ); + if (error != KErrNone) + User::Panic(_L("Failed to create test directory"), error); + + CTestScheduler* as = new CTestScheduler; + if (!as) + User::Panic(_L("Failed to create active scheduler"),KErrNoMemory); + CActiveScheduler::Install(as); // Install active scheduler + + CWapPushTestEngine* engine=NULL; + TRAPD(err,engine = CWapPushTestEngine::NewL()); + if (err != KErrNone) + User::Panic(_L("Failed to create test engine object"),err); + + // All the action happens within the main event loop + CActiveScheduler::Start(); + // Returned from start so shutdown + + delete engine; + + // Run OOM test cases. + TInt nextTest = 1; + TInt failAt = 0; + err = KErrNoMemory; + test.Start(_L("Starting OOM Test")); + while ( err != KErrNone ) + { + failAt++; + test.Printf ( KOOMTestStep, failAt ); + __UHEAP_SETFAIL( RHeap::EDeterministic, failAt ); + __UHEAP_MARK; + TRAP ( err, StartOomTestL ( nextTest ) ); + REComSession::FinalClose(); + __UHEAP_MARKEND; + __UHEAP_RESET; + } + delete as; + delete theCleanup; + test.End(); + test.Close(); +__UHEAP_MARKEND; + + User::Heap().Check(); + return(KErrNone); + } + + +