xml/wbxmlparser/test/rtest/tsrc/stabilitytestclass.cpp
changeset 0 e35f40988205
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // These tests are to allow the parser to parse a wide range of valid 
       
    15 // documents allowing for greater coverage of its functionality.
       
    16 // The fact that the documents are not parsed correctly is not the scope of
       
    17 // these tests, but instead the stability of the parser is.
       
    18 // The tests also incorporates indirect iTesting of the StringDictionaries
       
    19 // as the parser uses these during its paring phase.
       
    20 // If these iTest were to fail, it would give a good indication that the parser,
       
    21 // dictionary, or document being parsed where at fault. As the document being
       
    22 // parsed should never change (except for the addition of new documents),
       
    23 // this should narrow the search.
       
    24 // The output of what is parsed is withheld to speed up the processing of 
       
    25 // this automated iTest. Uncommenting the macro __SHOW_MANUAL_OUTPUT__ within 
       
    26 // the MMP file should allow for the output to be produced if the user so 
       
    27 // wishes.
       
    28 // Specific tests taking into account what the parser parses should also be
       
    29 // supplied for a fully comprehensive test suite.
       
    30 // 
       
    31 //
       
    32 
       
    33 #include <f32file.h>
       
    34 
       
    35 #include <ecom/ecom.h>
       
    36 #include <stringpool.h>
       
    37 #include <e32test.h>
       
    38 
       
    39 #include <xml/parserfeature.h>
       
    40 #include <xml/xmlframeworkerrors.h>
       
    41 
       
    42 #include "stabilitytestclass.h"
       
    43 #include "testdocuments.h"
       
    44 
       
    45 using namespace Xml;
       
    46 
       
    47 #ifdef __COMPARE_OUTPUT__
       
    48 #define INSERT_INTO_OUTPUT_BUFFER(output)  \
       
    49 						iOutput->Insert(iOutput->Length(), output)
       
    50 #define FORMAT_OUTPUT_BUFFER(format, data) \
       
    51 						iFormat->Format(format, data)
       
    52 
       
    53 #else
       
    54 #define INSERT_INTO_OUTPUT_BUFFER (output)
       
    55 #define FORMAT_OUTPUT_BUFFER (format, data)
       
    56 #endif //__COMPARE_OUTPUT__
       
    57 
       
    58 //
       
    59 // The way data is formatted:
       
    60 //   - Data is built up into iBuffer.
       
    61 //   - This is then inserted into iFormat, adding formatting, 
       
    62 //     e.g. start < and end >.
       
    63 //   - If the test compares the data this formatted data is then 
       
    64 //     inserted into iCompare for comparision.
       
    65 //   - iBuffer is cleared and rebuilt on each element.
       
    66 //   - iFormat is also used as a secondary buffer of iBuffer so as
       
    67 //     to convert TDesC8s into TDesC16s.
       
    68 //   - iOutput is only used for those tests that compare data,
       
    69 //     i.e. what's generated to what's expected.
       
    70 //
       
    71 
       
    72 
       
    73 
       
    74 CStabilityTestClass* CStabilityTestClass::NewL(RTest& aTest, 
       
    75 											   TBool aIsOomTest,
       
    76 											   TInt aChunkSize)
       
    77 	{
       
    78 	CStabilityTestClass* self = new(ELeave) CStabilityTestClass(aTest, aIsOomTest, aChunkSize);
       
    79 	CleanupStack::PushL(self);
       
    80 	self->ConstructL();
       
    81 	CleanupStack::Pop(self);
       
    82 	return self;
       
    83 	}
       
    84 
       
    85 
       
    86 CStabilityTestClass::CStabilityTestClass(RTest& aTest, 
       
    87 										 TBool aIsOomTest,
       
    88 										 TInt aChunkSize)
       
    89 :	iTest(aTest),
       
    90 	iChunkSize(aChunkSize),
       
    91 	iIsOomTest(aIsOomTest)
       
    92 	{
       
    93 	// do nothing;
       
    94 	}
       
    95 
       
    96 
       
    97 CStabilityTestClass::~CStabilityTestClass()
       
    98 	{
       
    99 	iFs.Close();
       
   100 	iCurrentIndex.Reset();
       
   101 	iEntries.ResetAndDestroy();
       
   102 
       
   103 #ifdef __COMPARE_OUTPUT__
       
   104 	delete iOutput;
       
   105 #endif // __COMPARE_OUTPUT__
       
   106 
       
   107 	delete iBuffer;
       
   108 
       
   109 #ifdef __SHOW_MANUAL_OUTPUT__
       
   110 	delete iFormat;
       
   111 #endif // __SHOW_MANUAL_OUTPUT__
       
   112 	}
       
   113 
       
   114 
       
   115 void CStabilityTestClass::ConstructL()
       
   116 	{
       
   117 	User::LeaveIfError(iFs.Connect());
       
   118 
       
   119 #ifdef __COMPARE_OUTPUT__
       
   120 	iOutput = new(ELeave) TBuf16<OUTPUT_SIZE>;
       
   121 #endif // __COMPARE_OUTPUT__
       
   122 
       
   123 	iBuffer = new(ELeave) TBuf16<BUFFER_SIZE>;
       
   124 
       
   125 #ifdef __SHOW_MANUAL_OUTPUT__
       
   126 	iFormat = new(ELeave) TBuf16<XBUFFER_SIZE>;
       
   127 #endif // __SHOW_MANUAL_OUTPUT__
       
   128 	}
       
   129 
       
   130 
       
   131 // From MContentHandler
       
   132 
       
   133 void CStabilityTestClass::OnStartDocumentL(const RDocumentParameters& /*aDocParam*/, TInt aErrorCode)
       
   134 	{
       
   135 	iTest.Printf(_L("CStabilityTestClass::OnStartDocumentL Error code:%d\n"), aErrorCode);
       
   136 	iError = aErrorCode;
       
   137 	}
       
   138 
       
   139 	
       
   140 void CStabilityTestClass::OnEndDocumentL(TInt aErrorCode)
       
   141 	{
       
   142 	iTest.Printf(_L("\nCStabilityTestClass::OnEndDocumentL Error code:%d\n"), aErrorCode);
       
   143 	iError = aErrorCode;
       
   144 	}
       
   145 
       
   146 	
       
   147 #ifdef __SHOW_MANUAL_OUTPUT__
       
   148 void CStabilityTestClass::OnStartElementL(const RTagInfo& aElement, const RAttributeArray& aAttribute, TInt aErrorCode)
       
   149 #else
       
   150 void CStabilityTestClass::OnStartElementL(const RTagInfo& /*aElement*/, const RAttributeArray& /*aAttribute*/, TInt aErrorCode)
       
   151 #endif
       
   152 	{
       
   153 	iError = aErrorCode;
       
   154 	
       
   155 #ifdef __SHOW_MANUAL_OUTPUT__
       
   156 	// element
       
   157 	iBuffer->Copy (aElement.LocalName().DesC());
       
   158 	
       
   159 	// check for the namespace
       
   160 	if (aElement.Uri().DesC() != KNullDesC8())
       
   161 		{
       
   162 		iBuffer->Append (_L(" xmlns=\'"));
       
   163 		iFormat->Copy(aElement.Uri().DesC());
       
   164 		iBuffer->Append (*iFormat);
       
   165 		iBuffer->Append (_L("\'"));
       
   166 		}
       
   167 
       
   168 	if (aAttribute.Count() == 0)
       
   169 		{
       
   170 		RDebug::Print(_L("<%S>"), iBuffer);	
       
   171 		
       
   172 		FORMAT_OUTPUT_BUFFER(_L("<%S>"), iBuffer);
       
   173 		INSERT_INTO_OUTPUT_BUFFER(*iFormat);
       
   174 		}
       
   175 	else
       
   176 		{
       
   177 		RPointerArray<TBuf16<256> > attr_list;
       
   178 
       
   179 		for (TInt p=0; p<aAttribute.Count(); ++p)
       
   180 			{
       
   181 			// Keep list of namespaces
       
   182 			
       
   183 			// check for the namespace
       
   184 			if ((aAttribute[p].Attribute().Uri().DesC() != aElement.Uri().DesC()) &&
       
   185 				(aAttribute[p].Attribute().Uri().DesC() != KNullDesC8))
       
   186 				{
       
   187 				TBuf16<256> *attr_ns = new(ELeave) TBuf16<256>;
       
   188 				TBool present=EFalse;
       
   189 				TInt x=0;
       
   190 				attr_ns->Copy(aAttribute[p].Attribute().Uri().DesC());
       
   191 
       
   192 				while (!present && x<attr_list.Count())
       
   193 					{
       
   194 					if (attr_list[x]->Compare(*attr_ns)==0)
       
   195 						{
       
   196 						present=ETrue;
       
   197 						}
       
   198 					else
       
   199 						{
       
   200 						++x;
       
   201 						}
       
   202 					}
       
   203 
       
   204 				if (!present)
       
   205 					{
       
   206 					attr_list.Append(attr_ns);
       
   207 					}
       
   208 				else
       
   209 					{
       
   210 					delete attr_ns;
       
   211 					}
       
   212 				}
       
   213 			}
       
   214 			
       
   215 		for (TInt j=0; j<attr_list.Count(); ++j)
       
   216 			{
       
   217 			iBuffer->Append (_L(" xmlns='"));
       
   218 			iBuffer->Append (*attr_list[j]);
       
   219 			iBuffer->Append (_L("'"));
       
   220 			}
       
   221 
       
   222 		RDebug::Print(_L("<%S"), iBuffer);
       
   223 		attr_list.ResetAndDestroy();
       
   224 
       
   225 		FORMAT_OUTPUT_BUFFER(_L("<%S"), iBuffer);
       
   226 		INSERT_INTO_OUTPUT_BUFFER(*iFormat);
       
   227 
       
   228 		for (TInt i=0; i<aAttribute.Count(); ++i)
       
   229 			{
       
   230 			RDebug::Print(_L(" "));
       
   231 			INSERT_INTO_OUTPUT_BUFFER(_L(" "));
       
   232 
       
   233 			// attribute
       
   234 			iBuffer->Copy(aAttribute[i].Attribute().LocalName().DesC());
       
   235 			iBuffer->Append(_L("=\""));
       
   236 
       
   237 			// value
       
   238 			iFormat->Copy(aAttribute[i].Value().DesC());
       
   239 
       
   240 			iBuffer->Append(*iFormat);
       
   241 			iBuffer->Append(_L("\""));
       
   242 			
       
   243 			RDebug::Print(_L("%S"), iBuffer);
       
   244 			
       
   245 			FORMAT_OUTPUT_BUFFER(_L("%S"), iBuffer);
       
   246 			INSERT_INTO_OUTPUT_BUFFER(*iFormat);
       
   247 			}
       
   248 		RDebug::Print(_L(">"));
       
   249 		INSERT_INTO_OUTPUT_BUFFER( _L(">"));
       
   250 		}
       
   251 #endif // __SHOW_MANUAL_OUTPUT__
       
   252 	}
       
   253 
       
   254 	
       
   255 #ifdef __SHOW_MANUAL_OUTPUT__
       
   256 void CStabilityTestClass::OnEndElementL(const RTagInfo& aElement, TInt aErrorCode)
       
   257 #else
       
   258 void CStabilityTestClass::OnEndElementL(const RTagInfo& /*aElement*/, TInt aErrorCode)
       
   259 #endif
       
   260 	{
       
   261 	iError = aErrorCode;
       
   262 
       
   263 #ifdef __SHOW_MANUAL_OUTPUT__
       
   264 	iBuffer->Copy (aElement.LocalName().DesC());
       
   265 	RDebug::Print(_L("</%S>"), iBuffer);
       
   266 
       
   267 	FORMAT_OUTPUT_BUFFER(_L("</%S>"), iBuffer);
       
   268 	INSERT_INTO_OUTPUT_BUFFER(*iFormat);
       
   269 
       
   270 #endif // __SHOW_MANUAL_OUTPUT__
       
   271 	}
       
   272 
       
   273 
       
   274 
       
   275 void CStabilityTestClass::OnContentL(const TDesC8& aBytes, TInt aErrorCode)
       
   276 	{
       
   277 	iError = aErrorCode;
       
   278 
       
   279   	iBuffer->Copy (aBytes);
       
   280 
       
   281    	if (aBytes.Length() && aBytes[0] == 0x02) // SyncML opaque data only
       
   282    		{
       
   283    		if (iParseMode & ERawContent)
       
   284 	   		{
       
   285 	   		// raw bytes	   		
       
   286 	   		// Write to a new file to be parsed later
       
   287 			RFile opaqueFile;
       
   288 			CleanupClosePushL(opaqueFile);
       
   289 			
       
   290 			// loose the last '\'
       
   291 			TPtrC path (iFileName.Path().Ptr(), iFileName.Path().Length()-1);
       
   292 			TInt pos = 0;
       
   293 			User::LeaveIfError(pos = path.LocateReverse('\\'));
       
   294 			TPtrC mid = path.Mid(++pos);
       
   295 			
       
   296 			TFileName name(KOpaqueDirectory());
       
   297 			name.Append (KDirSeperator());
       
   298 	
       
   299 			TInt err = KErrNone;
       
   300 			err = iFs.MkDirAll(name);
       
   301 			
       
   302 			if (err != KErrNone && err != KErrAlreadyExists)
       
   303 				{
       
   304 				User::Leave(err);
       
   305 				}
       
   306 
       
   307 			name.Append (mid);
       
   308 			name.Append (KUnderscore());
       
   309 			name.Append (iFileName.NameAndExt());
       
   310 
       
   311 			err = (opaqueFile.Replace(iFs, name, EFileWrite));
       
   312 			User::LeaveIfError(opaqueFile.Write(aBytes));
       
   313 
       
   314 			opaqueFile.Close();
       
   315 	   		CleanupStack::Pop(&opaqueFile);
       
   316 
       
   317 #ifdef __SHOW_MANUAL_OUTPUT__	   		
       
   318 	   		// Print the data to the logs anyway, even if its unreadable
       
   319 	   		for (TInt i=0; i<aBytes.Length(); ++i)
       
   320 	   			{
       
   321 	   			RDebug::Print(_L("%X"), aBytes[i]);
       
   322 	   			
       
   323 				FORMAT_OUTPUT_BUFFER(_L("%X"), aBytes[i]);
       
   324 				INSERT_INTO_OUTPUT_BUFFER(*iFormat);
       
   325 	   			}
       
   326 #endif // __SHOW_MANUAL_OUTPUT__
       
   327 	   		}
       
   328    		else
       
   329 	   		{
       
   330 	   		// utf8
       
   331 #ifdef __SHOW_MANUAL_OUTPUT__
       
   332 			RDebug::Print(_L("%S"), iBuffer);
       
   333 			
       
   334 			FORMAT_OUTPUT_BUFFER(_L("%S"), iBuffer);
       
   335 			INSERT_INTO_OUTPUT_BUFFER(*iFormat);
       
   336 			
       
   337 #endif // __SHOW_MANUAL_OUTPUT__
       
   338 	   		}
       
   339    		}
       
   340 	else
       
   341 		{
       
   342 #ifdef __SHOW_MANUAL_OUTPUT__
       
   343 		RDebug::Print(_L("%S"), iBuffer);
       
   344 
       
   345 		FORMAT_OUTPUT_BUFFER(_L("%S"), iBuffer);
       
   346 		INSERT_INTO_OUTPUT_BUFFER(*iFormat);
       
   347 
       
   348 #endif // __SHOW_MANUAL_OUTPUT__
       
   349 		}
       
   350 	}
       
   351 
       
   352 
       
   353 void CStabilityTestClass::OnStartPrefixMappingL(const RString& /*aPrefix*/, const RString& /*aUri*/, TInt /*aErrorCode*/)
       
   354 	{
       
   355 	// Not supported
       
   356 	iTest(EFalse);
       
   357 	}
       
   358 
       
   359 
       
   360 void CStabilityTestClass::OnEndPrefixMappingL(const RString& /*aPrefix*/, TInt /*aErrorCode*/)
       
   361 	{
       
   362 	// Not supported
       
   363 	iTest(EFalse);
       
   364 	}
       
   365 
       
   366 
       
   367 void CStabilityTestClass::OnIgnorableWhiteSpaceL(const TDesC8& /*aBytes*/, TInt /*aErrorCode*/)
       
   368 	{
       
   369 	// Not supported
       
   370 	iTest(EFalse);
       
   371 	}
       
   372 
       
   373 
       
   374 void CStabilityTestClass::OnSkippedEntityL(const RString& /*aName*/, TInt /*aErrorCode*/)
       
   375 	{
       
   376 	// Not supported
       
   377 	iTest(EFalse);
       
   378 	}
       
   379 
       
   380 
       
   381 #ifdef __SHOW_MANUAL_OUTPUT__
       
   382 void CStabilityTestClass::OnProcessingInstructionL(const TDesC8& aTarget, const TDesC8& aData, TInt aErrorCode)
       
   383 #else
       
   384 void CStabilityTestClass::OnProcessingInstructionL(const TDesC8& /*aTarget*/, const TDesC8& /*aData*/, TInt aErrorCode)
       
   385 #endif
       
   386 	{
       
   387 	iError = aErrorCode;
       
   388 
       
   389 #ifdef __SHOW_MANUAL_OUTPUT__
       
   390 	// attrstart	
       
   391 	iFormat->Copy (aTarget);
       
   392 	iFormat->Append(_L("=\""));
       
   393 	iBuffer->Append(*iFormat);
       
   394 
       
   395 	// attrvalue
       
   396 	iFormat->Copy(aData);
       
   397 	iFormat->Append(_L("\""));
       
   398 	iBuffer->Append(*iFormat);
       
   399 	
       
   400 	RDebug::Print(_L("{{%S}}"), iBuffer);
       
   401 
       
   402 	FORMAT_OUTPUT_BUFFER(_L("{{%S}}"), iBuffer);
       
   403 	INSERT_INTO_OUTPUT_BUFFER(*iFormat);
       
   404 	
       
   405 #endif // __SHOW_MANUAL_OUTPUT__
       
   406 	}
       
   407 
       
   408 
       
   409 #ifdef __SHOW_MANUAL_OUTPUT__
       
   410 void CStabilityTestClass::OnExtensionL(const RString& aData, TInt aToken, TInt aErrorCode)
       
   411 #else
       
   412 void CStabilityTestClass::OnExtensionL(const RString& /*aData*/, TInt /*aToken*/, TInt aErrorCode)
       
   413 #endif
       
   414 	{
       
   415 	iError = aErrorCode;
       
   416 
       
   417 #ifdef __SHOW_MANUAL_OUTPUT__
       
   418 	iBuffer->Copy (aData.DesC());
       
   419 	RDebug::Print(_L("[[0x%x : %S]]"), aToken, iBuffer);
       
   420 
       
   421 	FORMAT_OUTPUT_BUFFER(_L("[[0x%x : "), aToken);
       
   422 	INSERT_INTO_OUTPUT_BUFFER(*iFormat);
       
   423 	FORMAT_OUTPUT_BUFFER(_L("%S]]"), iBuffer);
       
   424 	INSERT_INTO_OUTPUT_BUFFER(*iFormat);
       
   425 
       
   426 #endif // __SHOW_MANUAL_OUTPUT__
       
   427 	}
       
   428 
       
   429 
       
   430 void CStabilityTestClass::OnError(TInt aErrorCode)
       
   431 	{
       
   432 	iError = aErrorCode;
       
   433 	iTest.Printf(_L("\nCStabilityTestClass::OnError Error code:%d\n"), aErrorCode);
       
   434 	}
       
   435 
       
   436 
       
   437 TAny* CStabilityTestClass::GetExtendedInterface(const TInt32 aUid)
       
   438 /**
       
   439 This method obtains the interface matching the specified uid.
       
   440 @return				0 if no interface matching the uid is found.
       
   441 					Otherwise, the this pointer cast to that interface.
       
   442 @param				aUid the uid identifying the required interface.
       
   443 */
       
   444 	{
       
   445 	if (aUid == MWbxmlExtensionHandler::EExtInterfaceUid)
       
   446 		{
       
   447 		return static_cast<MWbxmlExtensionHandler*>(this);
       
   448 		}
       
   449 	return 0;
       
   450 	}
       
   451 
       
   452 
       
   453 //----------------------------------------------------------------------------
       
   454 //Parser Tests
       
   455 
       
   456 
       
   457 void CStabilityTestClass::StabilityTestL(const TDesC& aAbsoluteDirPath, const TDesC& aExt, 
       
   458 										 ClassFuncPtrL aTestFuncL)
       
   459 	{
       
   460 	iTest.Next(_L("StabilityTestL"));
       
   461 
       
   462 	// Set up for heap leak checking
       
   463 	__UHEAP_MARK;
       
   464 
       
   465 	// and leaking thread handles
       
   466 	TInt startProcessHandleCount;
       
   467 	TInt startThreadHandleCount;
       
   468 	TInt endProcessHandleCount;
       
   469 	TInt endThreadHandleCount;
       
   470 
       
   471 	// Test Starts...
       
   472 
       
   473 	RThread thisThread;
       
   474 	thisThread.HandleCount(startProcessHandleCount, startThreadHandleCount);
       
   475 
       
   476 	//--------------
       
   477 
       
   478 	ParseDirL(aAbsoluteDirPath, aExt, aTestFuncL);
       
   479 	iEntries.Close();
       
   480 	iCurrentIndex.Close();
       
   481 
       
   482 
       
   483 	//--------------
       
   484 	// Check for open handles
       
   485 	thisThread.HandleCount(endProcessHandleCount, endThreadHandleCount);
       
   486 
       
   487 	iTest(startThreadHandleCount == endThreadHandleCount);
       
   488 
       
   489 	// Test Ends...
       
   490 
       
   491 	__UHEAP_MARKEND;
       
   492 	}
       
   493 
       
   494 
       
   495 void CStabilityTestClass::ParseDirL(const TDesC& aAbsoluteDirPath, 
       
   496 									const TDesC& aExt, ClassFuncPtrL aTestFuncL)
       
   497 	{
       
   498 	iError = KErrNone;
       
   499 
       
   500 	TFileName fileDirNameWithSep;
       
   501 	fileDirNameWithSep = aAbsoluteDirPath;
       
   502 	fileDirNameWithSep.Append(KDirSeperator);
       
   503 
       
   504 	CDir *dirList = NULL;
       
   505 	CDir *entries = NULL;
       
   506 
       
   507 	User::LeaveIfError (iFs.GetDir(fileDirNameWithSep, KEntryAttNormal|KEntryAttDir, ESortNone, entries, dirList));
       
   508 	delete dirList;
       
   509 	dirList = NULL;
       
   510 
       
   511 	iEntries.Append(entries);	
       
   512 	iCurrentIndex.Append(entries->Count());		
       
   513 
       
   514 	entries = NULL;
       
   515 	CleanupStack::PushL(iEntries[iEntries.Count()-1]);
       
   516 
       
   517 	// Point to last test that ran (OOM) or to be run
       
   518 	CDir*& entry = iEntries[iEntries.Count()-1];
       
   519 	TInt& ind = iCurrentIndex[iCurrentIndex.Count()-1];
       
   520 
       
   521 	TParse entryName;
       
   522 		
       
   523 	// Also acts as base test for recursiveness
       
   524 	while (--ind >= 0)
       
   525 		{
       
   526 		entryName.Set((*entry)[ind].iName, &fileDirNameWithSep, NULL);
       
   527 
       
   528 		if (!(*entry)[ind].IsDir())
       
   529 			{
       
   530 			if (entryName.Ext() == aExt)
       
   531 				{
       
   532 				ParseEntryL(entryName.FullName(), aTestFuncL);
       
   533 				}
       
   534 			}
       
   535 		else
       
   536 			{
       
   537 			ParseDirL(entryName.FullName(), aExt, aTestFuncL);
       
   538 			}
       
   539 		}
       
   540 	
       
   541 	CleanupStack::PopAndDestroy(iEntries[iEntries.Count()-1]);
       
   542 
       
   543 	iCurrentIndex.Remove(iCurrentIndex.Count()-1);
       
   544 	iEntries.Remove(iEntries.Count()-1);
       
   545 	}
       
   546 
       
   547 
       
   548 void CStabilityTestClass::ParseEntryL(const TDesC& aAbsoluteFilename,
       
   549 									  ClassFuncPtrL aTestFuncL)
       
   550 	{
       
   551 	// Need to set this for OnContentL
       
   552 	iFileName.Set (aAbsoluteFilename, NULL, NULL);
       
   553 	iTest.Printf(_L("\n"));
       
   554 
       
   555 	iParseMode = EErrorOnUnrecognisedTags|
       
   556 				 ERawContent;
       
   557 
       
   558 	if(iIsOomTest)
       
   559 		{
       
   560 		OomProcess(aTestFuncL);
       
   561 		}
       
   562 	else
       
   563 		{
       
   564 		(this->*aTestFuncL)(aAbsoluteFilename);
       
   565 		}
       
   566 	}
       
   567 
       
   568 
       
   569 void CStabilityTestClass::TestWholeL(const TDesC& aFileName)
       
   570 	{
       
   571 	iTest.Next(_L("TestWholeL"));
       
   572 	
       
   573 	// Set up for heap leak checking
       
   574 	__UHEAP_MARK;
       
   575 
       
   576 	// and leaking thread handles
       
   577 	TInt startProcessHandleCount;
       
   578 	TInt startThreadHandleCount;
       
   579 	TInt endProcessHandleCount;
       
   580 	TInt endThreadHandleCount;
       
   581 
       
   582 	// Test Starts...
       
   583 
       
   584 	RThread thisThread;
       
   585 	thisThread.HandleCount(startProcessHandleCount, startThreadHandleCount);
       
   586 
       
   587 	//--------------
       
   588 
       
   589 	iTest.Printf(_L("\nParsing document: %S\n"),&aFileName);
       
   590 
       
   591 	// Load the Parser and parse the buffer
       
   592 
       
   593 	iParser = CParser::NewLC(KWbxmlParserDataType, *this);
       
   594 	
       
   595 	User::LeaveIfError(iParser->EnableFeature(iParseMode));
       
   596 
       
   597 	// We parse to completion - parser will stop the ActiveSchedular
       
   598 	ParseL(*iParser, iFs, aFileName); 
       
   599 
       
   600 	CleanupStack::PopAndDestroy(iParser);
       
   601 	REComSession::FinalClose(); // Don't want leaks outside the iTest 
       
   602 
       
   603 
       
   604 	if(iIsOomTest)
       
   605 		{
       
   606 		// Only receives KErrNoMemory on OOM tests.
       
   607 		// Do this so the calling function knows we need to keep parsing 
       
   608 		// the same document.
       
   609 		if (iError == KErrNoMemory)
       
   610 			{
       
   611 			User::Leave(iError);
       
   612 			}
       
   613 		}
       
   614 	else
       
   615 		{	
       
   616 		iTest(iError == KErrNone);
       
   617 		}
       
   618 
       
   619 	//--------------
       
   620 	// Check for open handles
       
   621 	thisThread.HandleCount(endProcessHandleCount, endThreadHandleCount);
       
   622 
       
   623 	iTest(startThreadHandleCount == endThreadHandleCount);
       
   624 
       
   625 	// Test Ends...
       
   626 
       
   627 	__UHEAP_MARKEND;
       
   628 	}
       
   629 
       
   630 
       
   631 void CStabilityTestClass::TestChunkL(const TDesC& aFileName)
       
   632 	{
       
   633 	iTest.Next(_L("TestChunkL"));
       
   634 
       
   635 	// Create the Parser without a uid list 
       
   636 	// The data will be streamed a bit at a time
       
   637 	// so as to iTest the reaction of the parser.
       
   638 	// ===========================================
       
   639 
       
   640 	// Set up for heap leak checking
       
   641 	__UHEAP_MARK;
       
   642 
       
   643 	// and leaking thread handles
       
   644 	TInt startProcessHandleCount;
       
   645 	TInt startThreadHandleCount;
       
   646 	TInt endProcessHandleCount;
       
   647 	TInt endThreadHandleCount;
       
   648 
       
   649 	// Test Starts...
       
   650 
       
   651 	RThread thisThread;
       
   652 	thisThread.HandleCount(startProcessHandleCount, startThreadHandleCount);
       
   653 
       
   654 	//--------------
       
   655 
       
   656 	iTest.Printf(_L("\nParsing document: %S\n"),&aFileName);
       
   657 
       
   658 	// Read the file into the buffer
       
   659 
       
   660 	RFile xmlFile;
       
   661 	CleanupClosePushL(xmlFile);
       
   662 
       
   663 	User::LeaveIfError(xmlFile.Open(iFs, aFileName, EFileRead));
       
   664 
       
   665 	TInt streamSize;
       
   666 	User::LeaveIfError(xmlFile.Size(streamSize));
       
   667 
       
   668 	// Load the Parser and parse the buffer
       
   669 
       
   670 	iParser = CParser::NewLC(KWbxmlParserDataType, *this);
       
   671 	
       
   672 	User::LeaveIfError(iParser->EnableFeature(iParseMode));
       
   673 
       
   674 	// Always size to the max as we can not choose, compilation errors.
       
   675 	TBuf8<KMaxChunkSize> data;
       
   676 	User::LeaveIfError(xmlFile.Read(data, iChunkSize));
       
   677 	TInt length = data.Length();
       
   678 	
       
   679 	iError = KErrNone;
       
   680 	
       
   681 	while (length)
       
   682 		{
       
   683 		iParser->ParseL(data);
       
   684 		
       
   685 		// When no more data is read descriptors length is 0.
       
   686 		// Will throw another KErrEof
       
   687 		User::LeaveIfError(xmlFile.Read(data, iChunkSize));
       
   688 		length = data.Length();
       
   689 		}
       
   690 
       
   691 	iParser->ParseEndL();
       
   692 
       
   693 	// OnError should report only XML parsing specific errors
       
   694 	iTest(iError == KErrNone || iError <= KErrXmlFirst && iError >= KErrXmlLast);
       
   695 
       
   696 	CleanupStack::PopAndDestroy(iParser);
       
   697 	CleanupStack::PopAndDestroy(&xmlFile);         // Closes as well
       
   698 	REComSession::FinalClose(); // Don't want leaks outside the iTest 
       
   699 
       
   700 
       
   701 	//--------------
       
   702 	// Check for open handles
       
   703 	thisThread.HandleCount(endProcessHandleCount, endThreadHandleCount);
       
   704 
       
   705 	iTest(startThreadHandleCount == endThreadHandleCount);
       
   706 
       
   707 	// Test Ends...
       
   708 
       
   709 	__UHEAP_MARKEND;
       
   710 	}
       
   711 
       
   712 
       
   713 
       
   714 void CStabilityTestClass::OomProcess(ClassFuncPtrL aTestFuncL)
       
   715 	{	
       
   716 	iTest.Next(_L("OomProcess test"));
       
   717 	TInt err, tryCount = 0;
       
   718 	do
       
   719 		{
       
   720 		User::__DbgSetAllocFail(RHeap::EUser, RHeap::EFailNext, ++tryCount);
       
   721 		User::__DbgMarkStart(RHeap::EUser);
       
   722 		TRAP(err, (this->*aTestFuncL)(iFileName.FullName()));
       
   723 		User::__DbgMarkEnd(RHeap::EUser, 0);
       
   724 		} while(err==KErrNoMemory);
       
   725 
       
   726 	if(err==KErrNone)
       
   727 		{
       
   728 		// Reset
       
   729 		User::__DbgSetAllocFail(RHeap::EUser,RHeap::ENone,1);
       
   730 		}
       
   731 	else
       
   732 		{
       
   733 		User::Panic(_L("Unexpected leave reason"),err);
       
   734 		}
       
   735 
       
   736 	iTest.Printf(_L("- server succeeded at heap failure rate of %i\n"), tryCount);
       
   737 	}
       
   738 	
       
   739 	
       
   740 void CStabilityTestClass::TestBehaviour(const TDesC& aSrc, TPassOrFailureSettings& aTestSettings)
       
   741 	{
       
   742 	iTest.Next(_L("TestBehaviour"));
       
   743 
       
   744 	TRAPD(err, BehaviourTestL(aSrc, aTestSettings));
       
   745 	iTest (err == aTestSettings.iExpectedCode);
       
   746 	}
       
   747 	
       
   748 	
       
   749 void CStabilityTestClass::BehaviourTestL(const TDesC& aSrc, TPassOrFailureSettings& aTestSettings)
       
   750 	{
       
   751 	iTest.Next(_L("BehaviourTestL"));
       
   752 
       
   753 	// Test the parser with the values provided
       
   754 	// ===========================================
       
   755 
       
   756 	
       
   757 	// Set up for heap leak checking
       
   758 	__UHEAP_MARK;
       
   759 
       
   760 	// and leaking thread handles
       
   761 	TInt startProcessHandleCount;
       
   762 	TInt startThreadHandleCount;
       
   763 	TInt endProcessHandleCount;
       
   764 	TInt endThreadHandleCount;
       
   765 
       
   766 	// Test Starts...
       
   767 
       
   768 	RThread thisThread;
       
   769 	thisThread.HandleCount(startProcessHandleCount, startThreadHandleCount);
       
   770 
       
   771 	//--------------
       
   772 
       
   773 	iError = 0;
       
   774 
       
   775 	// iLoad the parser and parse the data
       
   776 
       
   777 	iParser = CParser::NewLC(KWbxmlParserDataType, *this);
       
   778 
       
   779 	iParser->AddPreloadedDictionaryL(*(aTestSettings.iStringDictionaryUri));
       
   780 
       
   781 	User::LeaveIfError(iParser->EnableFeature(aTestSettings.iParseMode));
       
   782 
       
   783 	if (aTestSettings.iDoParseDocument)
       
   784 		{
       
   785 		if (aTestSettings.iFilenameProvided)
       
   786 			{
       
   787 			ParseL(*iParser, iFs, aSrc);
       
   788 			}
       
   789 		else
       
   790 			{
       
   791 			TBuf8<256> buf8;
       
   792 			
       
   793 			// copy will ignore the upper byte if the byte-pair < 256, otherwise the value 1 is used.
       
   794 			buf8.Copy(aSrc);
       
   795 			
       
   796 			// whole file should be in descriptor/
       
   797 			ParseL(*iParser, buf8);
       
   798 			}
       
   799 		}
       
   800 					
       
   801 	CleanupStack::PopAndDestroy(iParser);
       
   802 
       
   803 	REComSession::FinalClose(); // Don't want leaks outside the iTest 
       
   804 
       
   805 
       
   806 	//--------------
       
   807 	// Check for open handles
       
   808 	thisThread.HandleCount(endProcessHandleCount, endThreadHandleCount);
       
   809 
       
   810 	iTest(startThreadHandleCount == endThreadHandleCount);
       
   811 
       
   812 	// Test Ends...
       
   813 
       
   814 	__UHEAP_MARKEND;	
       
   815 
       
   816 
       
   817 	User::LeaveIfError(iError);
       
   818 	}
       
   819