diff -r 000000000000 -r e35f40988205 xml/xmlexpatparser/test/rtest/tsrc/t_xmlparserheap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xml/xmlexpatparser/test/rtest/tsrc/t_xmlparserheap.cpp Thu Dec 17 09:29:21 2009 +0200 @@ -0,0 +1,223 @@ +// Copyright (c) 2003-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: +// This tests the failure of CExpat's internal heap. It is a separate test executable +// because it is statically linked to the xml parser object code and bypasses Ecom +// +// + +#include +#include "contenthandlers.h" +#include "xmlparserplugin.h" + +#include +#include + +using namespace Xml; + +GLDEF_D RTest test(_L("Expat heap test")); // must be called test, as the e32test macros rely on this + + +TPtrC8 KNamespaceTest = + _L8("" + "" + "" + "" + " " + " " + " " + " " + " " + " " + ""); + + +// --------------------------------------------------- + + +/** +@SYMTestCaseID SYSLIB-XML-CT-3746 +@SYMTestCaseDesc Creating OOM conditions and parsing. +@SYMTestPriority Medium +@SYMTestActions In OOM conditions, creating a parser and then parsing chunks. +@SYMTestExpectedResults The parser should behave as expected in the OOM conditions. +@SYMPREQ PREQ230 +*/ +LOCAL_C void ExpatOomTestL() + { + // + // Allocate paraphernalia required for CXmlParserPlugin + // + TSimpleContentHandler contentHandler; + + RElementStack elementStack; + CleanupClosePushL(elementStack); + + CCharSetConverter* charSetConverter = CCharSetConverter::NewL(); + CleanupStack::PushL(charSetConverter); + + RStringDictionaryCollection stringDictionaryCollection; + stringDictionaryCollection.OpenL(); + CleanupClosePushL(stringDictionaryCollection); + + TParserInitParams initParams; + initParams.iCharSetConverter = charSetConverter; + initParams.iContentHandler = &contentHandler; + initParams.iStringDictionaryCollection = &stringDictionaryCollection; + initParams.iElementStack = &elementStack; + + + /* + The following fragment forces the internal heap to fail during parser + construction and checks that this causes no leaks from the user heap + */ + TInt error; + TInt count = 0; + CXmlParserPlugin* parser = 0; + User::__DbgMarkStart(RHeap::EUser); + + do + { + User::__DbgMarkEnd(RHeap::EUser,0); + User::__DbgMarkStart(RHeap::EUser); + count++; + TRAP(error, parser=CXmlParserPlugin::NewL(&initParams, count)) + } while(error==KErrNoMemory); + + CleanupReleasePushL(*parser); + + + /* + Next we parse the namespace test file and cause the heap to heap to fail. + + Using the namespace test file ensures Expat is allocating prefixes and uri + bindings internally. + */ + count = 0; + RHeap* heap = parser->GetInternalHeap(); + heap->__DbgMarkStart(); + + TInt err=KErrNone; + do + { + contentHandler.iError = KErrNone; + + heap->__DbgMarkEnd(0); + heap->__DbgSetAllocFail(RHeap::EFailNext, ++count); + heap->__DbgMarkStart(); + TRAP(err, parser->ParseLastChunkL(KNamespaceTest)); + } while(err==KErrNoMemory); + + test(err==KErrNone); + heap->__DbgMarkEnd(0); + + + /* + Now set the user heap to fail on the next allocation and parse the + document again. This causes the CExpat handler function to leave, + in turn causing the parser to be de-allocated. + + This is in preparation for the next test. + */ + contentHandler.iError = KErrNone; + heap->__DbgSetAllocFail(RHeap::ENone,1); // __RHEAP_RESET + heap->__DbgMarkStart(); + User::__DbgSetAllocFail(RHeap::EUser, RHeap::EFailNext, 1); + TRAP(err, parser->ParseLastChunkL(KNamespaceTest)); + test(err==KErrNoMemory); + heap->__DbgMarkEnd(0); + + + /* + We have a CExpat in an error state with the internal parser deleted. Now + cause systematic heap failure while attempting to reset the parser and + parse a document. + + This will test reset failure and correct handling in CXmlParserPlugin. + */ + count = 0; + heap->__DbgMarkStart(); + + do + { + heap->__DbgMarkEnd(0); + heap->__DbgSetAllocFail(RHeap::EFailNext, ++count); + heap->__DbgMarkStart(); + parser->EnableFeature(EReportNamespaceMapping); + TRAP(err, parser->ParseLastChunkL(KNamespaceTest)); + + } while(err==KErrNoMemory); + + test(err==KErrNone); + heap->__DbgMarkEnd(0); + + CleanupStack::PopAndDestroy(4); + User::__DbgMarkEnd(RHeap::EUser,0); +} + + +// --------------------------------------------------- +// RunTestL +// MainL +// E32Main +// +// Top-level functions + + +LOCAL_C void RunTestL() + { + test.Start(_L(" @SYMTestCaseID:SYSLIB-XML-CT-3746 Expat parser Out-of-Memory test ")); + +// Ridiculous device to get around MSVC6 linker-compiler plot to rule the world +#ifdef _DEBUG + volatile TInt releaseBuild = 0; +#else + volatile TInt releaseBuild = 1; +#endif + + if(releaseBuild) + test.Printf(_L("This test is not supported in UREL builds\n")); + else + ExpatOomTestL(); + + test.End(); + } + +LOCAL_C void MainL() + { + CleanupClosePushL(test); + + TRAPD(error, RunTestL()); + test(error==KErrNone); + + CleanupStack::PopAndDestroy(&test); + } + +TInt E32Main() + { + __UHEAP_MARK; + CTrapCleanup* cleanup=CTrapCleanup::New(); + if(!cleanup) + return KErrNoMemory; + + TRAPD(error, MainL()); + + delete cleanup; + __UHEAP_MARKEND; + + return error; + }