// 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 <e32test.h>#include <e32svr.h> // for RDebug::Print#include <e32std.h>#include <flogger.h>#include "t_wappush.h"#include "pushtests.h"#include <push/pushmessage.h>// service setup includes...#include <msvstd.h>#include <msvids.h>#include "t_serviceutils.h"#include <pushentry.h>_LIT(KPushMtmDatFile, "z:\\system\\mtm\\WapPushMtmU.dat");_LIT(KMmsMtmDatFile, "c:\\system\\mtm\\mms.dat");_LIT(KWapPushTestTitle,"WAP Push tests");// 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?//class CTestScheduler : public CActiveScheduler { virtual void Error(TInt anError) const; };void CTestScheduler::Error(TInt anError) const { _LIT(KTestPanic,"CTestScheduler RunL leave"); User::Panic(KTestPanic,anError); }// cwappushtestenginevoid CWapPushTestEngine::DoCancel() { // cancel the current test if (iCurrentTest) iCurrentTest->Cancel(); }void CWapPushTestEngine::RunL() { switch (iState) { case EIdle: { TRAPD(err,RunNextTestL()) 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() { 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 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) { iState=EIdle; iTest=(TTest)(iTest+1); } else { 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 ESCRIPT: iCurrentTest = new (ELeave) CWapScriptTest(); break; default: // We've finished - set status to shut down and complete our own request SetPriority(EPriorityIdle); 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() { TMsvId pushService = KMsvNullIndexEntryId; TMsvId pushFolder = KMsvNullIndexEntryId; CWapPushTestMsgUtils* msgUtils = CWapPushTestMsgUtils::NewL(); CleanupStack::PushL(msgUtils); CMsvEntrySelection* idArray = new (ELeave) CMsvEntrySelection(); CleanupStack::PushL(idArray); // 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 TRAPD(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 //myTestUtils->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(idArray); // now set up MMS Services msgUtils->CreateMmsServiceL(); TRAPD(ignore2, msgUtils->InstallMtmGroupL(KMmsMtmDatFile)); CleanupStack::PopAndDestroy(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; _LIT(KPushLogDir, "push"); _LIT(KPushLogFile, "WapPushLogging.txt"); // 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<KWatcherLogBuffer> 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<KWatcherLogBuffer> 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<KWatcherLogBuffer> dateBuf; dateBuf.Format(KLogDateFmt, &buf); WPLPrintf(dateBuf); } } // X-Wap-Application-ID TBool isInt; TInt ID; TPtrC8 generalPtr; _LIT(KLogAppIdIntFmt,"App ID :\t%X"); foundField = aMessage.GetAppID(generalPtr, ID, isInt); if (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); } //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<KWatcherLogBuffer> hexBuf; TBuf<KWatcherLogBuffer> 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<KWatcherLogBuffer> buf; buf.Format(KErrorLogFmt,&aDescription,aError); buf.Append('\n'); WPLPrintf(buf); }// main loop//GLDEF_C TInt E32Main() {__UHEAP_MARK; // Install exception handler CTrapCleanup* theCleanup = CTrapCleanup::New(); 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 //RL: pause a sec to get a gander engine->Getch(); delete engine; delete as; delete theCleanup;__UHEAP_MARKEND; User::Heap().Check(); return(KErrNone); }