os/kernelhwsrv/kerneltest/e32test/debug/t_btrace.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2005-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 the License "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 // e32test\debug\t_btrace.cpp
    15 // Overview:
    16 // Tests generation of traces using the BTrace APIs
    17 // and captuirng of these by BTRACE.LDD and BTRACEC.DLL.
    18 // API Information:
    19 // class BTrace
    20 // class RBTrace
    21 // BTrace0
    22 // BTrace4
    23 // BTrace8
    24 // BTrace12
    25 // BTraceN
    26 // BTraceBig
    27 // BTracePc0
    28 // BTracePc4
    29 // BTracePc8
    30 // BTracePc12
    31 // BTracePcN
    32 // BTracePcBig
    33 // BTraceContext0
    34 // BTraceContext4
    35 // BTraceContext8
    36 // BTraceContext12
    37 // BTraceContextN
    38 // BTraceContextBig
    39 // BTraceContextPc0
    40 // BTraceContextPc4
    41 // BTraceContextPc8
    42 // BTraceContextPc12
    43 // BTraceContextPcN
    44 // BTraceContextPcBig
    45 // 
    46 //
    47 
    48 #define __E32TEST_EXTENSION__
    49 #include <e32test.h>
    50 #include <e32svr.h>
    51 #include <e32def.h>
    52 #include <e32def_private.h>
    53 
    54 #include "../../../kernel/eka/include/d32btrace.h"
    55 #include "../../../kernel/eka/include/e32btrace.h"
    56 #include "d_btrace.h"
    57 
    58 #define __TRACE_LINE__()	test.Printf(_L("%d\n"),__LINE__)
    59 
    60 RTest test(_L("T_BTRACE"));
    61 
    62 TUint BaseSize;		// Size of a standard test trace with no data
    63 
    64 RBTrace Trace;
    65 RBTraceTest TraceTest;
    66 
    67 TInt ContextOffset(const TUint8* aData)
    68 	{
    69 	TInt size = 4; // header size
    70 	if(aData[BTrace::EFlagsIndex]&BTrace::EHeader2Present)
    71 		size += 4;
    72 	if(aData[BTrace::EFlagsIndex]&BTrace::ETimestampPresent)
    73 		size += 4;
    74 	if(aData[BTrace::EFlagsIndex]&BTrace::ETimestamp2Present)
    75 		size += 4;
    76 	return size;
    77 	}
    78 
    79 
    80 TInt ExtraSize(const TUint8* aData)
    81 	{
    82 	TInt size = ContextOffset(aData);
    83 	if(aData[BTrace::EFlagsIndex]&BTrace::EContextIdPresent)
    84 		size += 4;
    85 	if(aData[BTrace::EFlagsIndex]&BTrace::EPcPresent)
    86 		size += 4;
    87 	if(aData[BTrace::EFlagsIndex]&BTrace::EExtraPresent)
    88 		size += 4;
    89 	return size;
    90 	}
    91 
    92 
    93 TUint32* Body(const TUint8* aData)
    94 	{
    95 	return (TUint32*)(aData+ExtraSize(aData));
    96 	}
    97 
    98 
    99 TPtrC8 Text(const TUint8* aData)
   100 	{
   101 	TInt size = aData[BTrace::ESizeIndex];
   102 	TInt extra = ExtraSize(aData);
   103 	extra += 8; // skip past first 2 32bit args
   104 	size -= extra;
   105 	return TPtrC8(aData+extra,size);
   106 	}
   107 
   108 
   109 const TUint KTest1SubCategory = 0x81;
   110 const TUint KTest2SubCategory = 0xc3;
   111 
   112 TUint8 KTestTrace1[KMaxBTraceRecordSize*2] = { BTrace::ETest1, KTest1SubCategory };
   113 TUint8 KTestTrace2[KMaxBTraceRecordSize*2] = { BTrace::ETest2, KTest2SubCategory };
   114 TUint32 BigFilter2[KNumBTraceFilterTestUids];
   115 
   116 void Trace1(TInt aSize, TInt aDelay=0)
   117 	{
   118 	test_KErrNone(TraceTest.Trace(0,KTestTrace1,aSize,aDelay));
   119 	}
   120 
   121 void Trace2(TInt aSize, TInt aDelay=0)
   122 	{
   123 	test_KErrNone(TraceTest.Trace(0,KTestTrace2,aSize,aDelay));
   124 	}
   125 
   126 TBool CheckTrace1(TUint8* aData, TInt aSize, TInt aSubCategory=KTest1SubCategory)
   127 	{
   128 	if(((aData[BTrace::ESizeIndex]+3)&~3)!=aSize)
   129 		return EFalse;
   130 	if(aData[BTrace::ECategoryIndex]!=BTrace::ETest1)
   131 		return EFalse;
   132 	if(aData[BTrace::ESubCategoryIndex]!=aSubCategory)
   133 		return EFalse;
   134 	TInt extra = ExtraSize(aData);
   135 	aSize = aData[BTrace::ESizeIndex]-extra;
   136 	aData += extra;
   137 	while(--aSize>=0)
   138 		{
   139 		if(((TUint8*)KTestTrace1)[4+aSize]!=aData[aSize])
   140 			return EFalse;
   141 		}
   142 	return ETrue;
   143 	}
   144 
   145 TBool CheckTrace2(TUint8* aData, TInt aSize, TInt aSubCategory=KTest2SubCategory)
   146 	{
   147 	if(((aData[BTrace::ESizeIndex]+3)&~3)!=aSize)
   148 		return EFalse;
   149 	if(aData[BTrace::ECategoryIndex]!=BTrace::ETest2)
   150 		return EFalse;
   151 	if(aData[BTrace::ESubCategoryIndex]!=aSubCategory)
   152 		return EFalse;
   153 	TInt extra = ExtraSize(aData);
   154 	aSize = aData[BTrace::ESizeIndex]-extra;
   155 	aData += extra;
   156 	while(--aSize>=0)
   157 		{
   158 		if(((TUint8*)KTestTrace2)[4+aSize]!=aData[aSize])
   159 			return EFalse;
   160 		}
   161 	return ETrue;
   162 	}
   163 
   164 
   165 TBool CheckSize(const TUint8* aData, TInt aSize, TInt aExpected)
   166 	{
   167 	TInt extra = ExtraSize(aData);
   168 	if(aSize==((extra+aExpected+3)&~3))
   169 		return 1;
   170 	else
   171 		{
   172 		TInt actual_size = aData[0];
   173 		if (aSize > actual_size)
   174 			actual_size = aSize;
   175 		test.Printf(_L("Trace data:\n"));
   176 		TInt i;
   177 		for (i=0; i<actual_size; ++i)
   178 			{
   179 			test.Printf(_L(" %02x"), aData[i]);
   180 			if ((i&15)==15 || i==actual_size-1)
   181 				test.Printf(_L("\n"));
   182 			}
   183 		test.Printf(_L("extra=%d aExp=%d aSize=%d\n"), extra, aExpected, aSize);
   184 		return 0;
   185 		}
   186 	}
   187 
   188 
   189 TInt Trace1Sequence = 0;
   190 TInt Trace2Sequence = 0;
   191 
   192 TUint8* TraceData;
   193 TInt TraceDataSize;
   194 
   195 TInt BadTrace(TUint8* aData)
   196 	{
   197 	Trace.SetMode(0);
   198 	TUint8* buffer = Trace.DataChunk().Base();
   199 	test.Printf(_L("BAD TRACE: data=%x buffer=%x (dataRead=%x,%x)\n"),aData,buffer,TraceData,TraceDataSize);
   200 	TUint8* bufferEnd =  buffer+((TUint32*)buffer)[1]; // TBTraceBuffer.iEnd
   201 	while(buffer<bufferEnd)
   202 		{
   203 		RDebug::Printf("%08x  %02x %02x %02x %02x  %02x %02x %02x %02x  %02x %02x %02x %02x  %02x %02x %02x %02x",
   204 			buffer,buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7],
   205 			buffer[8],buffer[9],buffer[10],buffer[11],buffer[12],buffer[13],buffer[14],buffer[15]);
   206 		buffer += 16;
   207 		}
   208 	buffer = Trace.DataChunk().Base();
   209 	TInt size = ((TUint32*)buffer)[9];
   210 	buffer += ((TUint32*)buffer)[8];
   211 	bufferEnd = buffer+size;
   212 	test.Printf(_L("copyBuffer=%x\n"),buffer,0);
   213 	while(buffer<bufferEnd)
   214 		{
   215 		RDebug::Printf("%08x  %02x %02x %02x %02x  %02x %02x %02x %02x  %02x %02x %02x %02x  %02x %02x %02x %02x",
   216 			buffer,buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7],
   217 			buffer[8],buffer[9],buffer[10],buffer[11],buffer[12],buffer[13],buffer[14],buffer[15]);
   218 		buffer += 16;
   219 		}
   220 	return 0;
   221 	}
   222 
   223 void CheckTraceData(TUint8* aData, TUint aSize)
   224 	{
   225 	TraceData = aData;
   226 	TraceDataSize = aSize;
   227 	TUint8* end = aData+aSize;
   228 	while(aData<end)
   229 		{
   230 		TUint size = (aData[BTrace::ESizeIndex]+3)&~3;
   231 		if(aData+size>end)
   232 			test(BadTrace(aData));
   233 		TUint subCategory = aData[BTrace::ESubCategoryIndex];
   234 		if(aData[BTrace::EFlagsIndex]&(BTrace::EMissingRecord))
   235 			{
   236 			Trace1Sequence = -1;
   237 			Trace2Sequence = -1;
   238 			}
   239 		if(aData[BTrace::ECategoryIndex]==BTrace::ETest1)
   240 			{
   241 			if(subCategory!=(TUint)Trace1Sequence && Trace1Sequence!=-1)
   242 				{
   243 				test.Printf(_L("Sequence wrong %02x!=%02x\n"),subCategory,Trace1Sequence);
   244 				test(BadTrace(aData));
   245 				}
   246 			if(!CheckTrace1(aData,size,subCategory))
   247 				test(BadTrace(aData));
   248 			Trace1Sequence = subCategory+1;
   249 			Trace1Sequence &= 0xff;
   250 			}
   251 		else
   252 			{
   253 			if(aData[BTrace::ECategoryIndex]!=BTrace::ETest2)
   254 				test(BadTrace(aData));
   255 			if(subCategory!=(TUint)Trace2Sequence && Trace2Sequence!=-1)
   256 				{
   257 				test.Printf(_L("Sequence wrong %02x!=%02x\n"),subCategory,Trace2Sequence);
   258 				test(BadTrace(aData));
   259 				}
   260 			if(!CheckTrace2(aData,size,subCategory))
   261 				test(BadTrace(aData));
   262 			Trace2Sequence = subCategory+1;
   263 			Trace2Sequence &= 0xff;
   264 			}
   265 		aData = BTrace::NextRecord(aData);
   266 		}
   267 	}
   268 
   269 
   270 void DumpTrace()
   271 	{
   272 	TBuf8<(80+KMaxBTraceDataArray*9/4)*2> buf;
   273 	for(;;)
   274 		{
   275 		TUint8* record;
   276 		TInt dataSize = Trace.GetData(record);
   277 		if(!dataSize)
   278 			break;
   279 		TUint8* end = record+dataSize;
   280 		while(record<end)
   281 			{
   282 			TUint size = record[BTrace::ESizeIndex];
   283 			TUint flags = record[BTrace::EFlagsIndex];
   284 			TUint category = record[BTrace::ECategoryIndex];
   285 			TUint subCategory = record[BTrace::ESubCategoryIndex];
   286 			TUint8* data = record+4;
   287 			size -= 4;
   288 
   289 			buf.Zero();
   290 			TUint32 header2 = 0;
   291 			if(flags&(BTrace::EHeader2Present))
   292 				{
   293 				header2 = *(TUint32*)data;
   294 				data += 4;
   295 				size -= 4;
   296 				}
   297 
   298 			if((flags&(BTrace::ETimestampPresent|BTrace::ETimestamp2Present))==(BTrace::ETimestampPresent|BTrace::ETimestamp2Present))
   299 				{
   300 				buf.AppendFormat(_L8("time:%08x:%08x "),((TUint32*)data)[1],*(TUint32*)data);
   301 				data += 8;
   302 				size -= 8;
   303 				}
   304 			else if(flags&(BTrace::ETimestampPresent|BTrace::ETimestamp2Present))
   305 				{
   306 				buf.AppendFormat(_L8("time:%08x "),*(TUint32*)data);
   307 				data += 4;
   308 				size -= 4;
   309 				}
   310 
   311 			if(flags&(BTrace::EContextIdPresent))
   312 				{
   313 				buf.AppendFormat(_L8("context:%08x "),*(TUint32*)data);
   314 				data += 4;
   315 				size -= 4;
   316 				}
   317 			else
   318 				{
   319 				buf.AppendFormat(_L8("                 "));
   320 				}
   321 
   322 			if(flags&(BTrace::EPcPresent))
   323 				{
   324 				buf.AppendFormat(_L8("pc:%08x "),*(TUint32*)data);
   325 				data += 4;
   326 				size -= 4;
   327 				}
   328 
   329 			TUint32 extra = 0;
   330 			if(flags&(BTrace::EExtraPresent))
   331 				{
   332 				extra = *(TUint32*)data;
   333 				data += 4;
   334 				size -= 4;
   335 				}
   336 
   337 			TUint32 data0 = (size>0) ? *(TUint32*)(data) : 0;
   338 			TUint32 data1 = (size>4) ? *(TUint32*)(data+4) : 0;
   339 			TUint32 data2 = (size>8) ? *(TUint32*)(data+8) : 0;
   340 			TPtrC8 des(0,0);
   341 			if(size>=8)
   342 				des.Set(data+8,size-8);
   343 			switch(category)
   344 				{
   345 			case BTrace::EKernPrintf:
   346 			case BTrace::ERDebugPrintf:
   347 			case BTrace::EPlatsecPrintf:
   348 				{
   349 				if(category==BTrace::EKernPrintf)
   350 					buf.Append(_L8("Kern::Printf "));
   351 				else if(category==BTrace::ERDebugPrintf)
   352 					buf.Append(_L8("RDebug::Printf "));
   353 				else
   354 					buf.Append(_L8("PlatSecPrintf "));
   355 				switch(header2&BTrace::EMultipartFlagMask)
   356 					{
   357 					case BTrace::EMultipartFirst:
   358 						buf.AppendFormat(_L8("seq:%d size:%d thread-id:%d \"%S\""),extra,data0,data1,&des);
   359 						break;
   360 					case BTrace::EMultipartMiddle:
   361 					case BTrace::EMultipartLast:
   362 						buf.AppendFormat(_L8("seq:%d size:%d offset:%d \"%S\""),extra,data0,data1,&des);
   363 						break;
   364 					default:
   365 						des.Set(data+4,size-4);
   366 						buf.AppendFormat(_L8("thread-id:%d \"%S\""),data0,&des);
   367 						break;
   368 						}
   369 				}
   370 				break;
   371 
   372 			case BTrace::EThreadIdentification:
   373 				{
   374 				switch(subCategory)
   375 					{
   376 				case BTrace::ENanoThreadCreate:
   377 					buf.AppendFormat(_L8("NanoThreadCreate  thrd:%08x"),data0);
   378 					break;
   379 				case BTrace::ENanoThreadDestroy:
   380 					buf.AppendFormat(_L8("NanoThreadDestroy thrd:%08x"),data0);
   381 					break;
   382 				case BTrace::EThreadCreate:
   383 					buf.AppendFormat(_L8("ThreadCreate      thrd:%08x proc:%08x name:%S"),data0,data1,&des);
   384 					break;
   385 				case BTrace::EThreadDestroy:
   386 					buf.AppendFormat(_L8("ThreadDestroy     thrd:%08x proc:%08x id:%d"),data0,data1,data2);
   387 					break;
   388 				case BTrace::EThreadName:
   389 					buf.AppendFormat(_L8("ThreadName        thrd:%08x proc:%08x name:%S"),data0,data1,&des);
   390 					break;
   391 				case BTrace::EThreadId:
   392 					buf.AppendFormat(_L8("ThreadId          thrd:%08x proc:%08x id:%d"),data0,data1,data2);
   393 					break;
   394 				case BTrace::EProcessName:
   395 					buf.AppendFormat(_L8("ProcessName       thrd:%08x proc:%08x name:%S"),data0,data1,&des);
   396 					break;
   397 					}
   398 				}
   399 				break;
   400 
   401 			case BTrace::ECpuUsage:
   402 				{
   403 				switch(subCategory)
   404 					{
   405 				case BTrace::EIrqStart:
   406 					buf.AppendFormat(_L8("IrqStart"));
   407 					break;
   408 				case BTrace::EIrqEnd:
   409 					buf.AppendFormat(_L8("IrqEnd"));
   410 					break;
   411 				case BTrace::EFiqStart:
   412 					buf.AppendFormat(_L8("FiqStart"));
   413 					break;
   414 				case BTrace::EFiqEnd:
   415 					buf.AppendFormat(_L8("FiqEnd"));
   416 					break;
   417 				case BTrace::EIDFCStart:
   418 					buf.AppendFormat(_L8("IDFCStart"));
   419 					break;
   420 				case BTrace::EIDFCEnd:
   421 					buf.AppendFormat(_L8("IDFCEnd"));
   422 					break;
   423 				case BTrace::ENewThreadContext:
   424 					buf.AppendFormat(_L8("NewThreadContext"));
   425 					break;
   426 					}
   427 				break;
   428 				}
   429 
   430 			case BTrace::EClientServer:
   431 				{
   432 				switch(subCategory)
   433 					{
   434 				case BTrace::EServerCreate:
   435 					buf.AppendFormat(_L8("EServerCreate     serv:%08x name:%S"),data0,&des);
   436 					break;
   437 				case BTrace::EServerDestroy:
   438 					buf.AppendFormat(_L8("EServerDestroy    serv:%08x"),data0);
   439 					break;
   440 				case BTrace::ESessionAttach:
   441 					buf.AppendFormat(_L8("ESessionAttach    sess:%08x serv:%08x"),data0,data1);
   442 					break;
   443 				case BTrace::ESessionDetach:
   444 					buf.AppendFormat(_L8("ESessionDetach    sess:%08x"),data0);
   445 					break;
   446 				case BTrace::EMessageSend:
   447 					buf.AppendFormat(_L8("EMessageSend      mess:%08x func:%08x sess:%08x"),data0,data1,data2);
   448 					break;
   449 				case BTrace::EMessageReceive:
   450 					buf.AppendFormat(_L8("EMessageReceive   mess:%08x"),data0);
   451 					break;
   452 				case BTrace::EMessageComplete:
   453 					buf.AppendFormat(_L8("EMessageComplete  mess:%08x reas:%08x"),data0,data1);
   454 					break;
   455 					}
   456 				break;
   457 				}
   458 
   459 			case BTrace::ERequests:
   460 				{
   461 				switch(subCategory)
   462 					{
   463 				case BTrace::ERequestComplete:
   464 					buf.AppendFormat(_L8("ERequestComplete  thrd:%08x stat:%08x resn:%08x"),data0,data1,data2);
   465 					break;
   466 					}
   467 				break;
   468 				}
   469 
   470 			default:
   471 				{
   472 				buf.AppendFormat(_L8("size:%d flags:%02x cat:%d,%d data: "),size,flags,category,subCategory);
   473 				for(TUint i=0; i<size; i+=4)
   474 					buf.AppendFormat(_L8("%08x "),*(TUint32*)(data+i));
   475 				}
   476 				break;
   477 				}
   478 			buf.Append('\r');
   479 			buf.Append('\n');
   480 			RDebug::RawPrint(buf.Expand());
   481 
   482 			record = BTrace::NextRecord(record);
   483 			}
   484 		Trace.DataUsed();
   485 		}
   486 	}
   487 
   488 
   489 //---------------------------------------------
   490 //! @SYMTestCaseID KBASE-T_BTRACE-0058-0059
   491 //! @SYMTestType UT
   492 //! @SYMPREQ PREQ1030
   493 //! @SYMTestCaseDesc Basic functionality tests which run in both 'sample' and 'free-running' modes.
   494 //! @SYMTestActions Test basic functionality provided by the functions:
   495 //!		RBTrace::SetFilter(), RBTrace::Empty(),
   496 //!		RBTrace::GetData(), RBTrace::DataUsed(),
   497 //!		RBTrace::RequestData(), RBTrace::CancelRequestData(),
   498 //!		RBTrace::BufferSize(), and RBTrace::ResizeBuffer()
   499 //! @SYMTestExpectedResults Function produce expected results.
   500 //! @SYMTestPriority High
   501 //! @SYMTestStatus Implemented
   502 //---------------------------------------------
   503 void TestBasics(TUint aMode)
   504 	{
   505 	aMode |= RBTrace::EEnable;
   506 
   507 	TUint8* data;
   508 	TInt size;
   509 
   510 	test.Start(_L("Check a second Open() fails"));
   511 	RBTrace dummy;
   512 	TInt r = dummy.Open();
   513 	test_Equal(KErrInUse,r);
   514 	r = dummy.Open();
   515 	test_Equal(KErrInUse,r);
   516 
   517 	test.Next(_L("Reset trace buffer"));
   518 	Trace.SetMode(0);
   519 	Trace.Empty();
   520 	Trace.SetMode(aMode);
   521 
   522 	TUint8* buffer_base = Trace.DataChunk().Base();
   523 	test.Printf(_L("Buffer base %08x\n"), buffer_base);
   524 
   525 	test.Next(_L("Test SetFilter() and GetData()"));
   526 	Trace.SetFilter(BTrace::ETest1,0);
   527 	Trace.SetFilter(BTrace::ETest2,0);
   528 	size = Trace.GetData(data);
   529 	test_Equal(0,size);
   530 	Trace1(4);
   531 	size = Trace.GetData(data);
   532 	test_Equal(0,size);
   533 	Trace2(4);
   534 	size = Trace.GetData(data);
   535 	test_Equal(0,size);
   536 	Trace.SetFilter(BTrace::ETest1,1);
   537 	Trace2(4);
   538 	size = Trace.GetData(data);
   539 	test_Equal(0,size);
   540 	Trace1(4);
   541 	size = Trace.GetData(data);
   542 	test(CheckSize(data,size,4));
   543 	BaseSize = size - 4;
   544 	test.Printf(_L("BaseSize=%d\n"), BaseSize);
   545 
   546 	test.Next(_L("Test Empty()"));
   547 	Trace.Empty();
   548 	size = Trace.GetData(data);
   549 	test_Equal(0,size);
   550 
   551 	test.Next(_L("Test DataUsed()"));
   552 	Trace1(0);
   553 	size = Trace.GetData(data);
   554 	test(CheckSize(data,size,0));
   555 	Trace.DataUsed();
   556 	size = Trace.GetData(data);
   557 	test_Equal(0,size);
   558 
   559 	test.Next(_L("Test RequestData()"));
   560 	TRequestStatus s1;
   561 	TRequestStatus s2;
   562 	RTimer timer;
   563 	test_KErrNone(timer.CreateLocal());
   564 
   565 	// immediate notification...
   566 	Trace.RequestData(s1,0);
   567 	test_Equal(KRequestPending, s1.Int());
   568 	timer.After(s2,5*1000000);
   569 	Trace1(4);
   570 	User::WaitForRequest(s1,s2);
   571 	test_KErrNone(s1.Int());
   572 	timer.Cancel();
   573 	User::WaitForRequest(s2);
   574 
   575 	// immediate notification with size>n ...
   576 	Trace.RequestData(s1,BaseSize+8);
   577 	test_Equal(KRequestPending,s1.Int());
   578 	timer.After(s2,5*1000000);
   579 	Trace1(20);
   580 	User::WaitForRequest(s1,s2);
   581 	test_KErrNone(s1.Int());
   582 	timer.Cancel();
   583 	User::WaitForRequest(s2);
   584 
   585 	size = Trace.GetData(data);
   586 	test_Compare(size, >= , BaseSize+8);
   587 	Trace.DataUsed();
   588 	size = Trace.GetData(data);
   589 	test_Equal(0,size);
   590 
   591 	// delayed notification...
   592 	Trace.RequestData(s1,0);
   593 	timer.After(s2,5*1000000);
   594 	Trace1(4,500000);
   595 	test_Equal(KRequestPending,s1.Int());
   596 	User::WaitForRequest(s1,s2);
   597 	test_KErrNone(s1.Int());
   598 	timer.Cancel();
   599 	User::WaitForRequest(s2);
   600 	size = Trace.GetData(data);
   601 	test(CheckSize(data,size,4));
   602 	Trace.DataUsed();
   603 
   604 	// delayed notification with size>n...
   605 	Trace.RequestData(s1,BaseSize+8);
   606 	Trace1(4,500000);
   607 	test_Equal(KRequestPending,s1.Int());
   608 	timer.After(s2,1000000);
   609 	User::WaitForRequest(s1,s2);
   610 	test_KErrNone(s2.Int());
   611 	timer.After(s2,5*1000000);
   612 	Trace1(20,500000);
   613 	test_Equal(KRequestPending,s1.Int());
   614 	User::WaitForRequest(s1,s2);
   615 	test_KErrNone(s1.Int());
   616 	timer.Cancel();
   617 	User::WaitForRequest(s2);
   618 
   619 	size = Trace.GetData(data);
   620 	test_Compare(size, >=, BaseSize+8);
   621 	Trace.DataUsed();
   622 	size = Trace.GetData(data);
   623 	test_Equal(0,size);
   624 
   625 	test.Next(_L("Test RequestData() when data is already available"));
   626 	Trace1(4);
   627 	Trace.RequestData(s1,0);
   628 	test_KErrNone(s1.Int());
   629 	User::WaitForRequest(s1);
   630 	size = Trace.GetData(data);
   631 	test(CheckSize(data,size,4));
   632 	Trace.DataUsed();
   633 	size = Trace.GetData(data);
   634 	test_Equal(0,size);
   635 
   636 	Trace1(4);
   637 	Trace.RequestData(s1,1);
   638 	test_KErrNone(s1.Int());
   639 	User::WaitForRequest(s1);
   640 	size = Trace.GetData(data);
   641 	test(CheckSize(data,size,4));
   642 	Trace.DataUsed();
   643 	size = Trace.GetData(data);
   644 	test_Equal(0,size);
   645 
   646 	test.Next(_L("Test RequestData() for ISR disabled traces"));
   647 	Trace.RequestData(s1,0);
   648 	test_Equal(KRequestPending,s1.Int());
   649 	timer.After(s2,5*1000000);
   650 	TraceTest.Trace(RBTraceTest::EContextIntsOff,KTestTrace1,4);
   651 	User::WaitForRequest(s1,s2);
   652 	test_KErrNone(s1.Int());
   653 	timer.Cancel();
   654 	User::WaitForRequest(s2);
   655 	size = Trace.GetData(data);
   656 	test(CheckSize(data,size,4));
   657 	Trace.DataUsed();
   658 	size = Trace.GetData(data);
   659 	test_Equal(0,size);
   660 
   661 	test.Next(_L("Test CancelRequestData()"));
   662 	Trace.RequestData(s1,0);
   663 	test_Equal(KRequestPending,s1.Int());
   664 	Trace.CancelRequestData();
   665 	User::WaitForRequest(s1);
   666 	test_Equal(KErrCancel,s1.Int());
   667 
   668 	test.Next(_L("Test trace data contents"));
   669 	Trace1(0);
   670 	size = Trace.GetData(data);
   671 	test(CheckSize(data,size,0));
   672  	test(CheckTrace1(data,size));
   673 	if(data[BTrace::EFlagsIndex]&BTrace::ETimestampPresent)
   674 		test.Printf(_L("Timestamps are present\n"));
   675 	else
   676 		test.Printf(_L("Timestamps are NOT present\n"));
   677 	Trace.DataUsed();
   678 
   679 	Trace1(4);
   680 	size = Trace.GetData(data);
   681 	test(CheckSize(data,size,4));
   682 	test(CheckTrace1(data,size));
   683 	Trace.DataUsed();
   684 
   685 	TInt i;
   686 	for(i=0; i<=8+(TInt)KMaxBTraceDataArray; i++)
   687 		{
   688 		Trace1(i);
   689 		size = Trace.GetData(data);
   690 		test(CheckSize(data,size,i));
   691 		test(CheckTrace1(data,size));
   692 		Trace.DataUsed();
   693 		}
   694 	Trace1(i);
   695 	size = Trace.GetData(data);
   696 	test(data[BTrace::EFlagsIndex]&BTrace::ERecordTruncated);
   697 	test(CheckSize(data,size,i-1));
   698 	test(CheckTrace1(data,size));
   699 	Trace.DataUsed();
   700 
   701 	test.Next(_L("Test BufferSize() and ResizeBuffer()"));
   702 	TInt oldSize = Trace.BufferSize();
   703 	Trace1(50);
   704 	size = Trace.GetData(data);
   705 	test(CheckSize(data,size,50));
   706 	r = Trace.ResizeBuffer(oldSize+0x1000);
   707 	test_KErrNone(r);
   708 	size = Trace.BufferSize();
   709 	test_Equal(oldSize+0x1000,size);
   710 	Trace.SetMode(aMode);
   711 	size = Trace.GetData(data);
   712 	test_Equal(0,size);
   713 	Trace1(40);
   714 	size = Trace.GetData(data);
   715 	test(CheckSize(data,size,40));
   716 	Trace.DataUsed();
   717 	r = Trace.ResizeBuffer(oldSize);
   718 	test_KErrNone(r);
   719 	size = Trace.BufferSize();
   720 	test_Equal(oldSize,size);
   721 
   722 	test.End();
   723 	}
   724 
   725 
   726 
   727 
   728 //---------------------------------------------
   729 //! @SYMTestCaseID KBASE-T_BTRACE-0060
   730 //! @SYMTestType UT
   731 //! @SYMPREQ PREQ1030
   732 //! @SYMTestCaseDesc Test traces generated from user code.
   733 //! @SYMTestActions Generate traces using BTrace0, BTrace4, BTrace8, BTrace12,
   734 //!		and BTraceN macros.
   735 //! @SYMTestExpectedResults All trace contents captured by RBTrace match those specified
   736 //!		at point of trace generation.
   737 //! @SYMTestPriority High
   738 //! @SYMTestStatus Implemented
   739 //---------------------------------------------
   740 void TestUserTrace(TUint aMode)
   741 	{
   742 	aMode |= RBTrace::EEnable;
   743 
   744 	TUint8* data;
   745 	TInt size;
   746 
   747 	test.Start(_L("Reset trace buffer"));
   748 	Trace.SetMode(0);
   749 	Trace.Empty();
   750 	Trace.SetMode(RBTrace::EEnable);
   751 	Trace.SetFilter(BTrace::ETest1,1);
   752 	Trace.SetFilter(BTrace::ETest2,0);
   753 
   754 	test.Next(_L("BTrace0"));
   755 	BTrace0(BTrace::ETest1,KTest1SubCategory);
   756 	size = Trace.GetData(data);
   757 	test(CheckSize(data,size,0));
   758 	test(CheckTrace1(data,size));
   759 	Trace.DataUsed();
   760 
   761 	test.Next(_L("BTrace4"));
   762 	BTrace4(BTrace::ETest1,KTest1SubCategory,*(TUint32*)(KTestTrace1+4));
   763 	size = Trace.GetData(data);
   764 	test(CheckSize(data,size,4));
   765 	test(CheckTrace1(data,size));
   766 	Trace.DataUsed();
   767 
   768 	test.Next(_L("BTrace8"));
   769 	BTrace8(BTrace::ETest1,KTest1SubCategory,*(TUint32*)(KTestTrace1+4),*(TUint32*)(KTestTrace1+8));
   770 	size = Trace.GetData(data);
   771 	test(CheckSize(data,size,8));
   772 	test(CheckTrace1(data,size));
   773 	Trace.DataUsed();
   774 
   775 	test.Next(_L("BTrace12"));
   776 	BTrace12(BTrace::ETest1,KTest1SubCategory,*(TUint32*)(KTestTrace1+4),*(TUint32*)(KTestTrace1+8),*(TUint32*)(KTestTrace1+12));
   777 	size = Trace.GetData(data);
   778 	test(CheckSize(data,size,12));
   779 	test(CheckTrace1(data,size));
   780 	Trace.DataUsed();
   781 
   782 	test.Next(_L("BTraceN"));
   783 	TInt i;
   784 	for(i=8; i<=8+(TInt)KMaxBTraceDataArray; i++)
   785 		{
   786 		BTraceN(BTrace::ETest1,KTest1SubCategory,*(TUint32*)(KTestTrace1+4),*(TUint32*)(KTestTrace1+8),KTestTrace1+12,i-8);
   787 		size = Trace.GetData(data);
   788 		test(CheckSize(data,size,i));
   789 		test(CheckTrace1(data,size));
   790 		Trace.DataUsed();
   791 		}
   792 	BTraceN(BTrace::ETest1,KTest1SubCategory,*(TUint32*)(KTestTrace1+4),*(TUint32*)(KTestTrace1+8),KTestTrace1+12,i-8);
   793 	size = Trace.GetData(data);
   794 	test(data[BTrace::EFlagsIndex]&BTrace::ERecordTruncated);
   795 	test(CheckSize(data,size,i-1));
   796 	test(CheckTrace1(data,size));
   797 	Trace.DataUsed();
   798 
   799 	test.End();
   800 	}
   801 
   802 
   803 TBool CompareFilter2(const TUint32* aUids, TInt aNumUids, TInt aGlobalFilter)
   804 	{
   805 	TUint32* filter2Buffer = (TUint32*)-1; // initialise to invalid value
   806 	TInt filter2Global = 0x80000000; // initialise to invalid value
   807 	TInt filter2Size = Trace.Filter2(filter2Buffer,filter2Global);
   808 
   809 	TBool pass = ETrue;
   810 	if(filter2Size!=aNumUids)
   811 		pass = EFalse;
   812 	else if(filter2Global!=aGlobalFilter)
   813 		pass = EFalse;
   814 	else if(0!=Mem::Compare((TUint8*)filter2Buffer,filter2Size,(TUint8*)aUids,aNumUids))
   815 		pass = EFalse;
   816 
   817 	delete filter2Buffer;
   818 	return pass;
   819 	}
   820 
   821 
   822 void TestFilter2()
   823 	{
   824 	test.Start(_L("Get filter2"));
   825 	TUint32* filter2Buffer = (TUint32*)-1; // initialise to invalid value
   826 	TInt filter2Global = 0x80000000; // initialise to invalid value
   827 	TInt filter2Size = Trace.Filter2(filter2Buffer,filter2Global);
   828 	test_NotNegative(filter2Size);
   829 	test_Compare(filter2Buffer, != , (TUint32*)-1);
   830 	test_Compare(filter2Global, != , -1);
   831 	test(CompareFilter2(filter2Buffer,filter2Size,filter2Global));
   832 	Trace.SetFilter(BTrace::ETest1,1);
   833 	TInt r;
   834 
   835 	test.Next(_L("Clear filter2"));
   836 	r = Trace.SetFilter2((TUint32*)0,0);
   837 	test_KErrNone(r);
   838 	Trace.SetFilter2(0);
   839 	test(CompareFilter2(0,0,0));
   840 
   841 #ifdef _DEBUG
   842 	test.Next(_L("Check SetFilter2's 'New' fails gracefully"));
   843 	__KHEAP_FAILNEXT(1);
   844 
   845 	r = Trace.SetFilter2(KBTraceFilterTestUid1,1);
   846 	test_Equal(KErrNoMemory, r);
   847 
   848 	__KHEAP_RESET;
   849 #endif
   850 
   851 	test.Next(_L("Test set and clear single uid"));
   852 	r = Trace.SetFilter2(KBTraceFilterTestUid1,0);
   853 	test_KErrNone(r);
   854 	test(CompareFilter2(0,0,0));
   855 	r = Trace.SetFilter2(KBTraceFilterTestUid1,1);
   856 	test_KErrNone(r);
   857 	test(CompareFilter2(&KBTraceFilterTestUid1,1,-1));
   858 	r = Trace.SetFilter2(KBTraceFilterTestUid1,0);
   859 	test_Equal(1,r);
   860 	test(CompareFilter2(0,0,0));
   861 
   862 	test.Next(_L("Test set multiple uid API"));
   863 	r = Trace.SetFilter2(&KBTraceFilterTestUid1,1);
   864 	test_KErrNone(r);
   865 	test(CompareFilter2(&KBTraceFilterTestUid1,1,-1));
   866 	r = Trace.SetFilter2(KBTraceFilterTestUid1,0);
   867 	test_Equal(1,r);
   868 	test(CompareFilter2(0,0,0));
   869 
   870 	test.Next(_L("Test set and clear uids with lots of permutations"));
   871 	TInt itterations = 0;
   872 	const TInt maxUids = 5;
   873 	TInt permute[maxUids] = {0};
   874 	TInt numUids;
   875 	RArray<TUint32> sortedArray(maxUids);
   876 	RArray<TUint32> array(maxUids);
   877 	for(numUids=1; numUids<=maxUids; ++numUids)
   878 		{
   879 		TInt p=0;
   880 		do
   881 			{
   882 			++itterations;
   883 			if(itterations==-1)
   884 				__BREAKPOINT(); // debuging breakpoint for a specific itteration
   885 
   886 			// make arrays of uids
   887 			sortedArray.Reset();
   888 			array.Reset();
   889 			TInt i;
   890 			for(i=0; i<numUids; ++i)
   891 				{
   892 				sortedArray.InsertInUnsignedKeyOrder(KBTraceFilterTestUid+permute[i]);
   893 				array.Append(KBTraceFilterTestUid+permute[i]);
   894 				}
   895 
   896 			// set filter using single uid api...
   897 			Trace.SetFilter2(0);
   898 			for(i=0; i<numUids; ++i)
   899 				{
   900 				r = Trace.SetFilter2(KBTraceFilterTestUid+permute[i],1);
   901 				test_NotNegative(r);
   902 				}
   903 			test(CompareFilter2(&sortedArray[0],sortedArray.Count(),-1));
   904 
   905 			// set filter using multiple uid api...
   906 			Trace.SetFilter2(0);
   907 			r = Trace.SetFilter2(&array[0],array.Count());
   908 			test_NotNegative(r);
   909 			test(CompareFilter2(&sortedArray[0],sortedArray.Count(),-1));
   910 
   911 			// remove uids...
   912 			for(i=0; i<numUids; ++i)
   913 				{
   914 				TUint32 removedUid = KBTraceFilterTestUid+permute[i];
   915 				TBool removed = EFalse;
   916 				r = sortedArray.FindInUnsignedKeyOrder(removedUid);
   917 				if(r>=0)
   918 					{
   919 					test(BTrace::CheckFilter2(BTrace::ETest1,removedUid));
   920 					sortedArray.Remove(r);
   921 					removed = ETrue;
   922 					}
   923 				r = Trace.SetFilter2(removedUid,0);
   924 				test_NotNegative(r);
   925 				if(removed)
   926 					{
   927 					test(!BTrace::CheckFilter2(BTrace::ETest1,removedUid));
   928 					}
   929 				r = sortedArray.Count();
   930 				if(r)
   931 					test(CompareFilter2(&sortedArray[0],r,-1));
   932 				else
   933 					{
   934 					test(CompareFilter2(0,0,0));
   935 					break;
   936 					}
   937 				}
   938 
   939 			// make next permutation
   940 			p=0;
   941 			while(p<numUids && ++permute[p] == numUids)
   942 				permute[p++] = 0;
   943 			}
   944 		while(p<numUids);
   945 		}
   946 
   947 	test.Next(_L("Test global filter"));
   948 	Trace.SetFilter2(0);
   949 	test(CompareFilter2(0,0,0));
   950 	Trace.SetFilter2(1);
   951 	test(CompareFilter2(0,0,1));
   952 	r = Trace.SetFilter2(KBTraceFilterTestUid1,1);
   953 	test_Equal(1,r);
   954 	test(CompareFilter2(0,0,1));
   955 	r = Trace.SetFilter2(KBTraceFilterTestUid1,0);
   956 	test_Equal(KErrNotSupported,r);
   957 	test(CompareFilter2(0,0,1));
   958 	r = Trace.SetFilter2(&KBTraceFilterTestUid1,1);
   959 	test_KErrNone(r);
   960 	test(CompareFilter2(&KBTraceFilterTestUid1,1,-1));
   961 
   962 	test.Next(_L("Restore filter2"));
   963 	r = Trace.SetFilter2(filter2Buffer,filter2Size);
   964 	test_KErrNone(r);
   965 	Trace.SetFilter2(filter2Global);
   966 	Trace.SetFilter(BTrace::ETest1,0);
   967 	delete filter2Buffer;
   968 
   969 	test.End();
   970 	}
   971 
   972 TUint32 ThisTraceContextId;
   973 
   974 void TestTrace1(TUint aType,TInt aSize)
   975 	{
   976 	if(!(aType&RBTraceTest::EUserTrace))
   977 		{
   978 		// use driver to create a kernel trace...
   979 		TraceTest.Trace(aType,KTestTrace1,aSize);
   980 		return;
   981 		}
   982 
   983 	TInt size = aSize;
   984 	TUint32* data = (TUint32*)KTestTrace1;
   985 	BTrace::TCategory category = BTrace::ETest1;
   986 	TUint subCategory = KTest1SubCategory;
   987 	TUint type = aType&0xff;
   988 	TBool bigTrace = aType&RBTraceTest::EBigTrace;
   989 	TBool filter2Trace = aType&RBTraceTest::EFilter2Trace;
   990 
   991 	if(!filter2Trace)
   992 		{
   993 		if(type==BTrace::EPcPresent)
   994 			{
   995 			if(bigTrace)
   996 				{
   997 				BTracePcBig(category,subCategory,data[1],data+2,size-4);
   998 				BTracePcBig(category,subCategory,data[1],data+2,size-4);
   999 				}
  1000 			else if(size==0)
  1001 				{
  1002 				BTracePc0(category,subCategory);
  1003 				BTracePc0(category,subCategory);
  1004 				}
  1005 			else if(size<=4)
  1006 				{
  1007 				BTracePc4(category,subCategory,data[1]);
  1008 				BTracePc4(category,subCategory,data[1]);
  1009 				}
  1010 			else if(size<=8)
  1011 				{
  1012 				BTracePc8(category,subCategory,data[1],data[2]);
  1013 				BTracePc8(category,subCategory,data[1],data[2]);
  1014 				}
  1015 			else
  1016 				{
  1017 				BTracePcN(category,subCategory,data[1],data[2],data+3,size-8);
  1018 				BTracePcN(category,subCategory,data[1],data[2],data+3,size-8);
  1019 				}
  1020 			}
  1021 		else if(type==BTrace::EContextIdPresent)
  1022 			{
  1023 			if(bigTrace)
  1024 				{
  1025 				BTraceContextBig(category,subCategory,data[1],data+2,size-4);
  1026 				BTraceContextBig(category,subCategory,data[1],data+2,size-4);
  1027 				}
  1028 			else if(size==0)
  1029 				{
  1030 				BTraceContext0(category,subCategory);
  1031 				BTraceContext0(category,subCategory);
  1032 				}
  1033 			else if(size<=4)
  1034 				{
  1035 				BTraceContext4(category,subCategory,data[1]);
  1036 				BTraceContext4(category,subCategory,data[1]);
  1037 				}
  1038 			else if(size<=8)
  1039 				{
  1040 				BTraceContext8(category,subCategory,data[1],data[2]);
  1041 				BTraceContext8(category,subCategory,data[1],data[2]);
  1042 				}
  1043 			else
  1044 				{
  1045 				BTraceContextN(category,subCategory,data[1],data[2],data+3,size-8);
  1046 				BTraceContextN(category,subCategory,data[1],data[2],data+3,size-8);
  1047 				}
  1048 			}
  1049 		else if(type==BTrace::EContextIdPresent+BTrace::EPcPresent)
  1050 			{
  1051 			if(bigTrace)
  1052 				{
  1053 				BTraceContextPcBig(category,subCategory,data[1],data+2,size-4);
  1054 				BTraceContextPcBig(category,subCategory,data[1],data+2,size-4);
  1055 				}
  1056 			else if(size==0)
  1057 				{
  1058 				BTraceContextPc0(category,subCategory);
  1059 				BTraceContextPc0(category,subCategory);
  1060 				}
  1061 			else if(size<=4)
  1062 				{
  1063 				BTraceContextPc4(category,subCategory,data[1]);
  1064 				BTraceContextPc4(category,subCategory,data[1]);
  1065 				}
  1066 			else if(size<=8)
  1067 				{
  1068 				BTraceContextPc8(category,subCategory,data[1],data[2]);
  1069 				BTraceContextPc8(category,subCategory,data[1],data[2]);
  1070 				}
  1071 			else
  1072 				{
  1073 				BTraceContextPcN(category,subCategory,data[1],data[2],data+3,size-8);
  1074 				BTraceContextPcN(category,subCategory,data[1],data[2],data+3,size-8);
  1075 				}
  1076 			}
  1077 		else
  1078 			{
  1079 			if(bigTrace)
  1080 				BTraceBig(category,subCategory,data[1],data+2,size-4);
  1081 			else if(size==0)
  1082 				BTrace0(category,subCategory);
  1083 			else if(size<=4)
  1084 				BTrace4(category,subCategory,data[1]);
  1085 			else if(size<8)
  1086 				BTrace8(category,subCategory,data[1],data[2]);
  1087 			else
  1088 				BTraceN(category,subCategory,data[1],data[2],data+3,size-8);
  1089 			}
  1090 		}
  1091 	else
  1092 		{
  1093 		if(type==BTrace::EPcPresent)
  1094 			{
  1095 			if(bigTrace)
  1096 				{
  1097 				BTraceFilteredPcBig(category,subCategory,data[1],data+2,size-4);
  1098 				BTraceFilteredPcBig(category,subCategory,data[1],data+2,size-4);
  1099 				}
  1100 			else if(size<4)
  1101 				{
  1102 				// invalid
  1103 				}
  1104 			else if(size==4)
  1105 				{
  1106 				BTraceFilteredPc4(category,subCategory,data[1]);
  1107 				BTraceFilteredPc4(category,subCategory,data[1]);
  1108 				}
  1109 			else if(size<=8)
  1110 				{
  1111 				BTraceFilteredPc8(category,subCategory,data[1],data[2]);
  1112 				BTraceFilteredPc8(category,subCategory,data[1],data[2]);
  1113 				}
  1114 			else
  1115 				{
  1116 				BTraceFilteredPcN(category,subCategory,data[1],data[2],data+3,size-8);
  1117 				BTraceFilteredPcN(category,subCategory,data[1],data[2],data+3,size-8);
  1118 				}
  1119 			}
  1120 		else if(type==BTrace::EContextIdPresent)
  1121 			{
  1122 			if(bigTrace)
  1123 				{
  1124 				BTraceFilteredContextBig(category,subCategory,data[1],data+2,size-4);
  1125 				BTraceFilteredContextBig(category,subCategory,data[1],data+2,size-4);
  1126 				}
  1127 			else if(size<4)
  1128 				{
  1129 				// invalid
  1130 				}
  1131 			else if(size==4)
  1132 				{
  1133 				BTraceFilteredContext4(category,subCategory,data[1]);
  1134 				BTraceFilteredContext4(category,subCategory,data[1]);
  1135 				}
  1136 			else if(size<=8)
  1137 				{
  1138 				BTraceFilteredContext8(category,subCategory,data[1],data[2]);
  1139 				BTraceFilteredContext8(category,subCategory,data[1],data[2]);
  1140 				}
  1141 			else
  1142 				{
  1143 				BTraceFilteredContextN(category,subCategory,data[1],data[2],data+3,size-8);
  1144 				BTraceFilteredContextN(category,subCategory,data[1],data[2],data+3,size-8);
  1145 				}
  1146 			}
  1147 		else if(type==BTrace::EContextIdPresent+BTrace::EPcPresent)
  1148 			{
  1149 			if(bigTrace)
  1150 				{
  1151 				BTraceFilteredContextPcBig(category,subCategory,data[1],data+2,size-4);
  1152 				BTraceFilteredContextPcBig(category,subCategory,data[1],data+2,size-4);
  1153 				}
  1154 			else if(size<4)
  1155 				{
  1156 				// invalid
  1157 				}
  1158 			else if(size==4)
  1159 				{
  1160 				BTraceFilteredContextPc4(category,subCategory,data[1]);
  1161 				BTraceFilteredContextPc4(category,subCategory,data[1]);
  1162 				}
  1163 			else if(size<=8)
  1164 				{
  1165 				BTraceFilteredContextPc8(category,subCategory,data[1],data[2]);
  1166 				BTraceFilteredContextPc8(category,subCategory,data[1],data[2]);
  1167 				}
  1168 			else
  1169 				{
  1170 				BTraceFilteredContextPcN(category,subCategory,data[1],data[2],data+3,size-8);
  1171 				BTraceFilteredContextPcN(category,subCategory,data[1],data[2],data+3,size-8);
  1172 				}
  1173 			}
  1174 		else
  1175 			{
  1176 			if(bigTrace)
  1177 				BTraceFilteredBig(category,subCategory,data[1],data+2,size-4);
  1178 			else if(size<4)
  1179 				{
  1180 				// invalid
  1181 				}
  1182 			else if(size==4)
  1183 				BTraceFiltered4(category,subCategory,data[1]);
  1184 			else if(size<8)
  1185 				BTraceFiltered8(category,subCategory,data[1],data[2]);
  1186 			else
  1187 				BTraceFilteredN(category,subCategory,data[1],data[2],data+3,size-8);
  1188 			}
  1189 		}
  1190 	}
  1191 
  1192 
  1193 
  1194 //---------------------------------------------
  1195 //! @SYMTestCaseID KBASE-T_BTRACE-0062-0063
  1196 //! @SYMTestType UT
  1197 //! @SYMPREQ PREQ1030
  1198 //! @SYMTestCaseDesc Test traces which specify thread context and/or program counter values.
  1199 //! @SYMTestActions Generate traces from user and kernel code using the BTracePcX,
  1200 //!		BTraceContextX and BTraceContextPcX macros. Kernel traces are additionaly
  1201 //!		generated in ISR and IDFC context.
  1202 //! @SYMTestExpectedResults All trace contents captured by RBTrace match those specified
  1203 //!		at point of trace generation. Also, where appropriate, PC and/or Context ID values
  1204 //!		are present and correct.
  1205 //! @SYMTestPriority High
  1206 //! @SYMTestStatus Implemented
  1207 //---------------------------------------------
  1208 void TestTrace(TBool aUserTrace, TBool aFilter2)
  1209 	{
  1210 	test.Start(_L("Reset trace buffer"));
  1211 	TInt oldSize = Trace.BufferSize();
  1212 	TInt r = Trace.ResizeBuffer(0x100000);
  1213 	test_KErrNone(r);
  1214 	Trace.SetMode(RBTrace::EEnable);
  1215 
  1216 	// dummy trace do get current thread context id
  1217 	Trace.SetFilter(BTrace::ETest1,0);
  1218 	ThisTraceContextId = TraceTest.Trace(BTrace::EContextIdPresent,KTestTrace1,0);
  1219 
  1220 	// create a test filter...
  1221 	TInt extraFlags = 0;
  1222 	if(aUserTrace)
  1223 		extraFlags |= RBTraceTest::EUserTrace;
  1224 	TInt minSize = 0;
  1225 	if(aFilter2)
  1226 		{
  1227 		extraFlags |= RBTraceTest::EFilter2Trace;
  1228 		minSize += 4;
  1229 		}
  1230 
  1231 	TInt filterMode;
  1232 	for(filterMode=0; filterMode<(aFilter2?6:2); ++filterMode)
  1233 		{
  1234 
  1235 		// setup filters...
  1236 		Trace.SetFilter(BTrace::ETest1,1);
  1237 		Trace.SetFilter2(BigFilter2,KNumBTraceFilterTestUids);
  1238 		if(filterMode==0 || filterMode==2)
  1239 			Trace.SetFilter(BTrace::ETest1,0); // disable in primary filter
  1240 		if(filterMode==0 || filterMode==1)
  1241 			Trace.SetFilter2(KBTraceFilterTestUid1,0); // disable in secondary filter
  1242 		if(filterMode==4)
  1243 			Trace.SetFilter2(0); // disable entire secondary filter
  1244 		if(filterMode==5)
  1245 			Trace.SetFilter2(1); // enable entire secondary filter
  1246 
  1247 		// expectTrace is true if we expect trace to be output...
  1248 		TBool expectTrace = aFilter2 ? (filterMode==3 || filterMode==5) : filterMode&1;
  1249 
  1250 		switch(filterMode)
  1251 			{
  1252 		case 0: test.Next(_L("Test with primary filter OFF, secondary filter OFF")); break;
  1253 		case 1: test.Next(_L("Test with primary filter ON, secondary filter OFF")); break;
  1254 		case 2: test.Next(_L("Test with primary filter OFF, secondary filter ON")); break;
  1255 		case 3: test.Next(_L("Test with primary filter ON, secondary filter ON")); break;
  1256 		case 4: test.Next(_L("Test with primary filter ON, global secondary filter OFF")); break;
  1257 		case 5: test.Next(_L("Test with primary filter ON, global secondary filter ON")); break;
  1258 			}
  1259 
  1260 		test.Start(_L("Traces without special context"));
  1261 		TInt i;
  1262 		for(i=minSize; i<=8+(TInt)KMaxBTraceDataArray; i++)
  1263 			{
  1264 			TestTrace1(extraFlags,i);
  1265 
  1266 			TUint8* data;
  1267 			TInt size;
  1268 			size = Trace.GetData(data);
  1269 			if(!expectTrace)
  1270 				{
  1271 				test(!size);
  1272 				continue;
  1273 				}
  1274 
  1275 			test(CheckSize(data,size,i));
  1276 			test(CheckTrace1(data,size,KTest1SubCategory));
  1277 
  1278 			test(!(data[BTrace::EFlagsIndex]&BTrace::EContextIdPresent));
  1279 			test(!(data[BTrace::EFlagsIndex]&BTrace::EPcPresent));
  1280 
  1281 			Trace.DataUsed();
  1282 			}
  1283 
  1284 		test.Next(_L("Traces with PC"));
  1285 		for(i=minSize; i<=8+(TInt)KMaxBTraceDataArray; i++)
  1286 			{
  1287 			TestTrace1(BTrace::EPcPresent|extraFlags,i);
  1288 
  1289 			TUint8* data;
  1290 			TUint8* data2;
  1291 			TInt size;
  1292 			size=Trace.GetData(data);
  1293 			if(!expectTrace)
  1294 				{
  1295 				test(!size);
  1296 				continue;
  1297 				}
  1298 			size /= 2;
  1299 			data2 = data+size;
  1300 
  1301 			test(CheckSize(data,size,i));
  1302 			test(CheckTrace1(data,size,KTest1SubCategory));
  1303 
  1304 			test(CheckSize(data2,size,i));
  1305 			test(CheckTrace1(data2,size,KTest1SubCategory));
  1306 
  1307 			test(!(data[BTrace::EFlagsIndex]&BTrace::EContextIdPresent));
  1308 			test((data[BTrace::EFlagsIndex]&BTrace::EPcPresent));
  1309 
  1310 			TInt offset = ContextOffset(data);
  1311 			test_Compare( ((TUint32*)(data+offset))[0], != ,((TUint32*)(data2+offset))[0]);
  1312 
  1313 			Trace.DataUsed();
  1314 			}
  1315 
  1316 		test.Next(_L("Traces with Context ID"));
  1317 		for(i=minSize; i<=8+(TInt)KMaxBTraceDataArray; i++)
  1318 			{
  1319 			TestTrace1(BTrace::EContextIdPresent|extraFlags,i);
  1320 
  1321 			TUint8* data;
  1322 			TUint8* data2;
  1323 			TInt size;
  1324 			size=Trace.GetData(data);
  1325 			if(!expectTrace)
  1326 				{
  1327 				test(!size);
  1328 				continue;
  1329 				}
  1330 			size /= 2;
  1331 			data2 = data+size;
  1332 
  1333 			test(CheckSize(data,size,i));
  1334 			test(CheckTrace1(data,size,KTest1SubCategory));
  1335 
  1336 			test(CheckSize(data2,size,i));
  1337 			test(CheckTrace1(data2,size,KTest1SubCategory));
  1338 
  1339 			test((data[BTrace::EFlagsIndex]&BTrace::EContextIdPresent));
  1340 			test(!(data[BTrace::EFlagsIndex]&BTrace::EPcPresent));
  1341 
  1342 			TUint offset = ContextOffset(data);
  1343 			test_Equal(ThisTraceContextId, ((TUint32*)(data+offset))[0]);
  1344 			test_Equal(ThisTraceContextId, ((TUint32*)(data2+offset))[0]);
  1345 			Trace.DataUsed();
  1346 			}
  1347 
  1348 		test.Next(_L("Traces with Context ID and PC"));
  1349 		for(i=minSize; i<=8+(TInt)KMaxBTraceDataArray; i++)
  1350 			{
  1351 			TestTrace1(BTrace::EContextIdPresent|BTrace::EPcPresent|extraFlags,i);
  1352 
  1353 			TUint8* data;
  1354 			TUint8* data2;
  1355 			TInt size;
  1356 			size=Trace.GetData(data);
  1357 			if(!expectTrace)
  1358 				{
  1359 				test(!size);
  1360 				continue;
  1361 				}
  1362 			size /= 2;
  1363 			data2 = data+size;
  1364 
  1365 			test(CheckSize(data,size,i));
  1366 			test(CheckTrace1(data,size,KTest1SubCategory));
  1367 
  1368 			test(CheckSize(data2,size,i));
  1369 			test(CheckTrace1(data2,size,KTest1SubCategory));
  1370 
  1371 			test((data[BTrace::EFlagsIndex]&BTrace::EContextIdPresent));
  1372 			test((data[BTrace::EFlagsIndex]&BTrace::EPcPresent));
  1373 
  1374 			TUint offset = ContextOffset(data);
  1375 
  1376 			test_Equal(ThisTraceContextId, ((TUint32*)(data+offset))[0]);
  1377 			test_Equal(ThisTraceContextId, ((TUint32*)(data2+offset))[0]);
  1378 			test_Compare( ((TUint32*)(data+offset))[1], != ,((TUint32*)(data2+offset))[1]);
  1379 
  1380 			Trace.DataUsed();
  1381 			}
  1382 
  1383 		if(!aUserTrace)
  1384 			{
  1385 			test.Next(_L("Traces with Context ID in ISR mode"));
  1386 			for(i=minSize; i<=8+(TInt)KMaxBTraceDataArray; i++)
  1387 				{
  1388 				TraceTest.Trace(BTrace::EContextIdPresent|RBTraceTest::EContextIsr|extraFlags,KTestTrace1,i);
  1389 
  1390 				TUint8* data;
  1391 				TUint8* data2;
  1392 				TInt size;
  1393 				size=Trace.GetData(data);
  1394 				if(!expectTrace)
  1395 					{
  1396 					test(!size);
  1397 					continue;
  1398 					}
  1399 				size /= 2;
  1400 				data2 = data+size;
  1401 
  1402 				test(CheckSize(data,size,i));
  1403 				test(CheckTrace1(data,size,KTest1SubCategory));
  1404 
  1405 				test(CheckSize(data2,size,i));
  1406 				test(CheckTrace1(data2,size,KTest1SubCategory));
  1407 
  1408 				test((data[BTrace::EFlagsIndex]&BTrace::EContextIdPresent));
  1409 				test(!(data[BTrace::EFlagsIndex]&BTrace::EPcPresent));
  1410 
  1411 				TUint offset = ContextOffset(data);
  1412 				test( ((TUint32*)(data+offset))[0] == 2 );
  1413 				test( ((TUint32*)(data2+offset))[0] == 2 );
  1414 
  1415 				Trace.DataUsed();
  1416 				}
  1417 
  1418 			test.Next(_L("Traces with Context ID in IDFC mode"));
  1419 			for(i=minSize; i<=8+(TInt)KMaxBTraceDataArray; i++)
  1420 				{
  1421 				TraceTest.Trace(BTrace::EContextIdPresent|RBTraceTest::EContextIDFC|extraFlags,KTestTrace1,i);
  1422 
  1423 				TUint8* data;
  1424 				TUint8* data2;
  1425 				TInt size;
  1426 				size=Trace.GetData(data);
  1427 				if(!expectTrace)
  1428 					{
  1429 					test(!size);
  1430 					continue;
  1431 					}
  1432 				size /= 2;
  1433 				data2 = data+size;
  1434 
  1435 				test(CheckSize(data,size,i));
  1436 				test(CheckTrace1(data,size,KTest1SubCategory));
  1437 
  1438 				test(CheckSize(data2,size,i));
  1439 				test(CheckTrace1(data2,size,KTest1SubCategory));
  1440 
  1441 				test((data[BTrace::EFlagsIndex]&BTrace::EContextIdPresent));
  1442 				test(!(data[BTrace::EFlagsIndex]&BTrace::EPcPresent));
  1443 
  1444 				TUint offset = ContextOffset(data);
  1445 				test( ((TUint32*)(data+offset))[0] == 3 );
  1446 				test( ((TUint32*)(data2+offset))[0] == 3 );
  1447 
  1448 				Trace.DataUsed();
  1449 				}
  1450 			}
  1451 		test.End();
  1452 		r = Trace.ResizeBuffer(0x100000);	// avoid buffer wrap problems
  1453 		test_KErrNone(r);
  1454 		Trace.SetMode(RBTrace::EEnable);
  1455 		}
  1456 
  1457 	test.Next(_L("Restore buffer"));
  1458 	r = Trace.ResizeBuffer(oldSize);
  1459 	test_KErrNone(r);
  1460 	Trace.SetFilter2(0);
  1461 
  1462 	test.End();
  1463 	}
  1464 
  1465 
  1466 TUint32 BigTraceId = 0;
  1467 
  1468 TBool BigTraceFirst = 0;
  1469 TBool BigTraceMiddle = 0;
  1470 TBool BigTraceEnd = 0;
  1471 
  1472 void BigTraceBeginTest()
  1473 	{
  1474 	BigTraceFirst = 0;
  1475 	BigTraceMiddle = 0;
  1476 	BigTraceEnd = 0;
  1477 	}
  1478 
  1479 TBool BigTraceEndTest()
  1480 	{
  1481 	return BigTraceFirst&&BigTraceMiddle&&BigTraceEnd;
  1482 	}
  1483 
  1484 TBool DoCheckBigTrace1(TUint8*& aData, TUint32 aOutSize, TUint32& aOffset, TUint32 aExtraIds = 0)
  1485 	{
  1486 	TUint32* ptr = (TUint32*)aData;
  1487 	if(aData[BTrace::ECategoryIndex]!=BTrace::ETest1)
  1488 		return EFalse;
  1489 	if(aData[BTrace::ESubCategoryIndex]!=KTest1SubCategory)
  1490 		return EFalse;
  1491 //	TUint32 header = *ptr++;
  1492 	++ptr;
  1493 
  1494 	if(aData[BTrace::EFlagsIndex]&BTrace::ERecordTruncated)
  1495 		return EFalse;
  1496 
  1497 	if(!(aData[BTrace::EFlagsIndex]&BTrace::EHeader2Present))
  1498 		return EFalse;
  1499 	TUint32 header2 = *ptr++;
  1500 	if(aData[BTrace::EFlagsIndex]&BTrace::ETimestampPresent)
  1501 		++ptr;
  1502 	if(aData[BTrace::EFlagsIndex]&BTrace::ETimestamp2Present)
  1503 		++ptr;
  1504 
  1505 	if(aData[BTrace::EFlagsIndex]&BTrace::EContextIdPresent)
  1506 		++ptr;
  1507 	if(aData[BTrace::EFlagsIndex]&BTrace::EPcPresent)
  1508 		++ptr;
  1509 
  1510 	if(!(aData[BTrace::EFlagsIndex]&BTrace::EExtraPresent))
  1511 		return EFalse;
  1512 	TUint id = *ptr++;
  1513 
  1514 	if(*ptr++ != aOutSize)
  1515 		return EFalse;
  1516 
  1517 	if(aOffset && *ptr++ != aOffset)
  1518 		return EFalse;
  1519 
  1520 	TInt size = aData[BTrace::ESizeIndex]-((TInt)ptr-(TInt)aData);
  1521 	TUint8* data = (TUint8*)ptr;
  1522 	TUint8* out = (TUint8*)KTestTrace1+4+aOffset;
  1523 
  1524 	if(!aOffset)
  1525 		{
  1526 		if((header2&BTrace::EMultipartFlagMask) != BTrace::EMultipartFirst)
  1527 			return EFalse;
  1528 		BigTraceId = id;
  1529 		aOffset += size-4-aExtraIds;
  1530 		BigTraceFirst = ETrue;
  1531 		}
  1532 	else
  1533 		{
  1534 		if(id!=BigTraceId)
  1535 			return EFalse;
  1536 		aOffset += size;
  1537 		out += 4 + aExtraIds;
  1538 		if(aOffset==aOutSize)
  1539 			{
  1540 			if((header2&BTrace::EMultipartFlagMask) != BTrace::EMultipartLast)
  1541 				return EFalse;
  1542 			BigTraceEnd = ETrue;
  1543 			}
  1544 		else
  1545 			{
  1546 			if((header2&BTrace::EMultipartFlagMask) != BTrace::EMultipartMiddle)
  1547 				return EFalse;
  1548 			BigTraceMiddle = ETrue;
  1549 			}
  1550 		}
  1551 	if(aOffset>aOutSize)
  1552 		return EFalse;
  1553 
  1554 	while(--size>=0)
  1555 		if(*data++!=*out++)
  1556 			return EFalse;
  1557 	aData = data;
  1558 
  1559 	return ETrue;
  1560 	}
  1561 
  1562 
  1563 
  1564 TBool CheckBigTrace1(TUint8* aData, TInt aSize, TInt aOutSize, TInt aSubCategory=KTest1SubCategory, TUint32 aExtraIds = 0)
  1565 	{
  1566 	if(aOutSize<=(TInt)KMaxBTraceDataArray+8)
  1567 		{
  1568 		if(!CheckSize(aData,aSize,aOutSize))
  1569 			return EFalse;
  1570 		if(!CheckTrace1(aData,aSize,aSubCategory))
  1571 			return EFalse;
  1572 		}
  1573 	else
  1574 		{
  1575 		TUint8* end = aData+aSize;
  1576 		aOutSize -= 4 + aExtraIds; // first 4 bytes of trace are always present, and don't count towards 'size' of multipart trace
  1577 		TUint32 aOffset = 0;
  1578 		while(aOffset<TUint32(aOutSize))
  1579 			if(!DoCheckBigTrace1(aData,aOutSize,aOffset,aExtraIds))
  1580 				return EFalse;
  1581 		aData = (TUint8*)(((TInt)aData+3)&~3);
  1582 		if(aData != end)
  1583 			return EFalse;
  1584 		}
  1585 	return ETrue;
  1586 	}
  1587 
  1588 
  1589 //---------------------------------------------
  1590 //! @SYMTestCaseID KBASE-T_BTRACE-0061
  1591 //! @SYMTestType UT
  1592 //! @SYMPREQ PREQ1030
  1593 //! @SYMTestCaseDesc Test Big (mutipart) kernel traces.
  1594 //! @SYMTestActions Generate traces from kernel code using the BTraceBig,
  1595 //!		BTracePcBig, BTraceContextBig and BTraceContextPcBig macros.
  1596 //! @SYMTestExpectedResults Traces where broken down into mutiple parts and
  1597 //!		all trace contents captured by RBTrace matched those specified
  1598 //!		at point of trace generation. Also, where appropriate, PC and/or
  1599 //!		Context ID values are present and correct.
  1600 //! @SYMTestPriority High
  1601 //! @SYMTestStatus Implemented
  1602 //---------------------------------------------
  1603 void TestBig(TBool aUserTrace, TBool aFilter2)
  1604 	{
  1605 	test.Start(_L("Reset trace buffer"));
  1606 	TInt oldSize = Trace.BufferSize();
  1607 	TInt r = Trace.ResizeBuffer(0x100000);
  1608 	test_KErrNone(r);
  1609 	Trace.SetMode(RBTrace::EEnable);
  1610 
  1611 	// dummy trace do get current thread context id
  1612 	Trace.SetFilter(BTrace::ETest1,0);
  1613 	ThisTraceContextId = TraceTest.Trace(BTrace::EContextIdPresent,KTestTrace1,0);
  1614 
  1615 	// create a test filter...
  1616 	TInt extraFlags = 0;
  1617 	if(aUserTrace)
  1618 		extraFlags |= RBTraceTest::EUserTrace;
  1619 	TInt minSize = 4;
  1620 	if(aFilter2)
  1621 		{
  1622 		extraFlags |= RBTraceTest::EFilter2Trace;
  1623 		minSize += 4;
  1624 		}
  1625 
  1626 	TInt filterMode;
  1627 	for(filterMode=0; filterMode<(aFilter2?6:2); ++filterMode)
  1628 		{
  1629 
  1630 		// setup filters...
  1631 		Trace.SetFilter(BTrace::ETest1,1);
  1632 		Trace.SetFilter2(BigFilter2,KNumBTraceFilterTestUids);
  1633 		if(filterMode==0 || filterMode==2)
  1634 			Trace.SetFilter(BTrace::ETest1,0); // disable in primary filter
  1635 		if(filterMode==0 || filterMode==1)
  1636 			Trace.SetFilter2(KBTraceFilterTestUid1,0); // disable in secondary filter
  1637 		if(filterMode==4)
  1638 			Trace.SetFilter2(0); // disable entire secondary filter
  1639 		if(filterMode==5)
  1640 			Trace.SetFilter2(1); // enable entire secondary filter
  1641 
  1642 		// expectTrace is true if we expect trace to be output...
  1643 		TBool expectTrace = aFilter2 ? (filterMode==3 || filterMode==5) : filterMode&1;
  1644 
  1645 		switch(filterMode)
  1646 			{
  1647 		case 0: test.Next(_L("Test with primary filter OFF, secondary filter OFF")); break;
  1648 		case 1: test.Next(_L("Test with primary filter ON, secondary filter OFF")); break;
  1649 		case 2: test.Next(_L("Test with primary filter OFF, secondary filter ON")); break;
  1650 		case 3: test.Next(_L("Test with primary filter ON, secondary filter ON")); break;
  1651 		case 4: test.Next(_L("Test with primary filter ON, global secondary filter OFF")); break;
  1652 		case 5: test.Next(_L("Test with primary filter ON, global secondary filter ON")); break;
  1653 			}
  1654 
  1655 		test.Start(_L("Big traces without special context"));
  1656 		TInt i;
  1657 		for(i=minSize; i<=(TInt)sizeof(KTestTrace1)-4; i++)
  1658 			{
  1659 			TestTrace1(RBTraceTest::EBigTrace|extraFlags,i);
  1660 
  1661 			TUint8* data;
  1662 			TInt size;
  1663 			size = Trace.GetData(data);
  1664 			if(!expectTrace)
  1665 				{
  1666 				test(!size);
  1667 				continue;
  1668 				}
  1669 			test(CheckBigTrace1(data,size,i,KTest1SubCategory));
  1670 			Trace.DataUsed();
  1671 			}
  1672 
  1673 		test.Next(_L("Big traces with PC"));
  1674 		BigTraceBeginTest();
  1675 		for(i=minSize; i<=(TInt)sizeof(KTestTrace1)-4; i++)
  1676 			{
  1677 			TraceTest.Trace(RBTraceTest::EBigTrace|BTrace::EPcPresent|extraFlags,KTestTrace1,i);
  1678 
  1679 			TUint8* data;
  1680 			TUint8* data2;
  1681 			TInt size;
  1682 			size=Trace.GetData(data);
  1683 			if(!expectTrace)
  1684 				{
  1685 				test(!size);
  1686 				continue;
  1687 				}
  1688 			size /= 2;
  1689 			data2 = data+size;
  1690 
  1691 			test(CheckBigTrace1(data,size,i,KTest1SubCategory));
  1692 			test(CheckBigTrace1(data2,size,i,KTest1SubCategory));
  1693 
  1694 			test(!(data[BTrace::EFlagsIndex]&BTrace::EContextIdPresent));
  1695 			test((data[BTrace::EFlagsIndex]&BTrace::EPcPresent));
  1696 
  1697 			TInt offset = ContextOffset(data);
  1698 			test( ((TUint32*)(data+offset))[0] != ((TUint32*)(data2+offset))[0]);
  1699 
  1700 			Trace.DataUsed();
  1701 			}
  1702 		test_Equal(expectTrace,BigTraceEndTest()); // check we actually got mutilpart traces
  1703 
  1704 		test.Next(_L("Big traces with Context ID"));
  1705 		BigTraceBeginTest();
  1706 		for(i=minSize; i<=(TInt)sizeof(KTestTrace1)-4; i++)
  1707 			{
  1708 			TestTrace1(RBTraceTest::EBigTrace|BTrace::EContextIdPresent|extraFlags,i);
  1709 
  1710 			TUint8* data;
  1711 			TUint8* data2;
  1712 			TInt size;
  1713 			size=Trace.GetData(data);
  1714 			if(!expectTrace)
  1715 				{
  1716 				test(!size);
  1717 				continue;
  1718 				}
  1719 			size /= 2;
  1720 			data2 = data+size;
  1721 
  1722 			test(CheckBigTrace1(data,size,i,KTest1SubCategory));
  1723 			test(CheckBigTrace1(data2,size,i,KTest1SubCategory));
  1724 
  1725 			test((data[BTrace::EFlagsIndex]&BTrace::EContextIdPresent));
  1726 			test(!(data[BTrace::EFlagsIndex]&BTrace::EPcPresent));
  1727 
  1728 			TUint offset = ContextOffset(data);
  1729 			test_Equal(ThisTraceContextId, ((TUint32*)(data+offset))[0]);
  1730 			test_Equal(ThisTraceContextId, ((TUint32*)(data2+offset))[0]);
  1731 
  1732 			Trace.DataUsed();
  1733 			}
  1734 		test_Equal(expectTrace,BigTraceEndTest()); // check we actually got mutilpart traces
  1735 
  1736 		test.Next(_L("Big traces with Context ID and PC"));
  1737 		BigTraceBeginTest();
  1738 		for(i=minSize; i<=(TInt)sizeof(KTestTrace1)-4; i++)
  1739 			{
  1740 			TestTrace1(RBTraceTest::EBigTrace|BTrace::EContextIdPresent|BTrace::EPcPresent|extraFlags,i);
  1741 
  1742 			TUint8* data;
  1743 			TUint8* data2;
  1744 			TInt size;
  1745 			size=Trace.GetData(data);
  1746 			if(!expectTrace)
  1747 				{
  1748 				test(!size);
  1749 				continue;
  1750 				}
  1751 			size /= 2;
  1752 			data2 = data+size;
  1753 
  1754 			test(CheckBigTrace1(data,size,i,KTest1SubCategory));
  1755 			test(CheckBigTrace1(data2,size,i,KTest1SubCategory));
  1756 
  1757 			test((data[BTrace::EFlagsIndex]&BTrace::EContextIdPresent));
  1758 			test((data[BTrace::EFlagsIndex]&BTrace::EPcPresent));
  1759 
  1760 			TUint offset = ContextOffset(data);
  1761 			test_Equal(ThisTraceContextId, ((TUint32*)(data+offset))[0] );
  1762 			test_Equal(ThisTraceContextId, ((TUint32*)(data2+offset))[0] );
  1763 			test_Compare( ((TUint32*)(data+offset))[1], != ,((TUint32*)(data2+offset))[1]);
  1764 
  1765 			Trace.DataUsed();
  1766 			}
  1767 		test_Equal(expectTrace,BigTraceEndTest()); // check we actually got mutilpart traces
  1768 		test.End();
  1769 		}
  1770 
  1771 	test.Next(_L("Restore buffer"));
  1772 	r = Trace.ResizeBuffer(oldSize);
  1773 	test_KErrNone(r);
  1774 	Trace.SetFilter2(0);
  1775 
  1776 	test.End();
  1777 	}
  1778 
  1779 
  1780 TUint MainThreadTraceId = 0;
  1781 
  1782 //---------------------------------------------
  1783 //! @SYMTestCaseID KBASE-T_BTRACE-0064
  1784 //! @SYMTestType UT
  1785 //! @SYMPREQ PREQ1030
  1786 //! @SYMTestCaseDesc Test BTrace category EThreadIdentification.
  1787 //! @SYMTestActions Enable the EThreadIdentification trace category, causing it to be 'primed'.
  1788 //!		Rename a thread and a process, then create and destory a thread.
  1789 //!		No actions are performed if the kernel doesn't support this trace category.
  1790 //! @SYMTestExpectedResults All test actions produced traces and their contents matched
  1791 //!		the expected results.
  1792 //! @SYMTestPriority High
  1793 //! @SYMTestStatus Implemented
  1794 //---------------------------------------------
  1795 void TestThreadIdentification()
  1796 	{
  1797 	if(KErrNotSupported==Trace.Filter(BTrace::EThreadIdentification))
  1798 		{
  1799 		test.Start(_L("Trace category not supported by this build of kernel."));
  1800 		test.End();
  1801 		return;
  1802 		}
  1803 
  1804 	TBuf8<KMaxKernelName> threadName = RThread().Name().Collapse();
  1805 	TUint threadId = RThread().Id();
  1806 	TBuf8<KMaxKernelName> processName = RProcess().Name().Collapse();
  1807 
  1808 	TUint32 threadTraceId = 0;
  1809 	TUint32 processTraceId = 0;
  1810 	TUint8* data;
  1811 	TInt size;
  1812 
  1813 	test.Start(_L("Reset trace buffer"));
  1814 	Trace.SetMode(0);
  1815 	TInt oldSize = Trace.BufferSize();
  1816 	TInt r = Trace.ResizeBuffer(0x100000);
  1817 	test_KErrNone(r);
  1818 	Trace.SetFilter(BTrace::EThreadIdentification,0);
  1819 	Trace.SetMode(RBTrace::EEnable);
  1820 
  1821 	test.Next(_L("Test category is primed correct when it is enabled"));
  1822 	Trace.SetFilter(BTrace::EThreadIdentification,1);
  1823 	// search for current thread in trace...
  1824 	TUint8* trace;
  1825 	size=Trace.GetData(trace);
  1826 	test_NotNull(size);
  1827 	TUint8* end = trace+size;
  1828 	for(data=trace; data<end; data=BTrace::NextRecord(data))
  1829 		if(data[BTrace::ECategoryIndex]==BTrace::EThreadIdentification)
  1830 			if(data[BTrace::ESubCategoryIndex]==BTrace::EProcessName)
  1831 				if(processName==Text(data))
  1832 					{
  1833 					processTraceId = Body(data)[1];
  1834 					break;
  1835 					}
  1836 	test_Compare(data, < , end);
  1837 	for(; data<end; data=BTrace::NextRecord(data))
  1838 		if(data[BTrace::ECategoryIndex]==BTrace::EThreadIdentification)
  1839 			if(data[BTrace::ESubCategoryIndex]==BTrace::EThreadName)
  1840 				if(processTraceId==Body(data)[1])
  1841 					if(threadName==Text(data))
  1842 						{
  1843 						threadTraceId = Body(data)[0];
  1844 						break;
  1845 						}
  1846 	test_Compare(data, < , end);
  1847 	for(; data<end; data=BTrace::NextRecord(data))
  1848 		if(data[BTrace::ECategoryIndex]==BTrace::EThreadIdentification)
  1849 			if(data[BTrace::ESubCategoryIndex]==BTrace::EThreadId)
  1850 				if(threadTraceId==Body(data)[0])
  1851 					if(processTraceId==Body(data)[1])
  1852 						if(threadId==Body(data)[2])
  1853 							{
  1854 							break;
  1855 							}
  1856 	test_Compare(data, < ,end);
  1857 	Trace.DataUsed();
  1858 	MainThreadTraceId = threadTraceId;
  1859 
  1860 	test.Next(_L("Test thread rename traces"));
  1861 	test_KErrNone(User::RenameThread(_L("t_btrace-main")));
  1862 	threadName = RThread().Name().Collapse();
  1863 	size=Trace.GetData(data);
  1864 	test_NotNull(size);
  1865 	end = data+size;
  1866 	test_Equal(BTrace::EThreadIdentification,data[BTrace::ECategoryIndex]);
  1867 	test_Equal(BTrace::EThreadName, data[BTrace::ESubCategoryIndex]);
  1868 	test_Equal(threadTraceId, Body(data)[0]);
  1869 	test_Equal(processTraceId, Body(data)[1]);
  1870 	test(threadName==Text(data));
  1871 	data=BTrace::NextRecord(data);
  1872 	test(data==end);
  1873 	Trace.DataUsed();
  1874 
  1875 	test.Next(_L("Test process rename traces"));
  1876 	test_KErrNone(User::RenameProcess(_L("T_BTRACE-renamed")));
  1877 	processName = RProcess().Name().Collapse();
  1878 	size=Trace.GetData(data);
  1879 	test_NotNull(size);
  1880 	end = data+size;
  1881 	test_Equal(BTrace::EThreadIdentification,data[BTrace::ECategoryIndex]);
  1882 	test_Equal(BTrace::EProcessName ,data[BTrace::ESubCategoryIndex]);
  1883 	test_Equal(processTraceId, Body(data)[1]);
  1884 	test(processName==Text(data));
  1885 	data=BTrace::NextRecord(data);
  1886 	test(data==end);
  1887 	Trace.DataUsed();
  1888 
  1889 	test.Next(_L("Test thread creation traces"));
  1890 	RThread thread;
  1891 	test_KErrNone(thread.Create(KNullDesC,0,0x1000,&User::Allocator(),0));
  1892 	threadName = thread.Name().Collapse();
  1893 	threadId = thread.Id();
  1894 	size=Trace.GetData(data);
  1895 	test_NotNull(size);
  1896 	end = data+size;
  1897 
  1898 	test_Equal(BTrace::EThreadIdentification,data[BTrace::ECategoryIndex]);
  1899 	test_Equal(BTrace::ENanoThreadCreate ,data[BTrace::ESubCategoryIndex]);
  1900 	threadTraceId = Body(data)[0];
  1901 	data=BTrace::NextRecord(data);
  1902 	test_Compare(data, < ,end);
  1903 
  1904 	test_Equal(BTrace::EThreadIdentification,data[BTrace::ECategoryIndex]);
  1905 	test_Equal(BTrace::EProcessName ,data[BTrace::ESubCategoryIndex]);
  1906 	test_Equal(processTraceId, Body(data)[1]);
  1907 	test(processName==Text(data));
  1908 	data=BTrace::NextRecord(data);
  1909 	test_Compare(data, < ,end);
  1910 
  1911 	test_Equal(BTrace::EThreadIdentification,data[BTrace::ECategoryIndex]);
  1912 	test_Equal(BTrace::EThreadCreate ,data[BTrace::ESubCategoryIndex]);
  1913 	test_Equal(threadTraceId, Body(data)[0]);
  1914 	processTraceId = Body(data)[1];
  1915 	test(threadName==Text(data));
  1916 	data=BTrace::NextRecord(data);
  1917 	test_Compare(data, < ,end);
  1918 
  1919 	test_Equal(BTrace::EThreadIdentification,data[BTrace::ECategoryIndex]);
  1920 	test_Equal(BTrace::EThreadId ,data[BTrace::ESubCategoryIndex]);
  1921 	test_Equal(threadTraceId, Body(data)[0]);
  1922 	test_Equal(processTraceId, Body(data)[1]);
  1923 	test(threadId==Body(data)[2]);
  1924 	data=BTrace::NextRecord(data);
  1925 	test_Equal(data,end);
  1926 	Trace.DataUsed();
  1927 
  1928 	test.Next(_L("Test thread destruction traces"));
  1929 	thread.Kill(0);
  1930 	User::After(100000);
  1931 	size=Trace.GetData(data);
  1932 	test_NotNull(size);
  1933 	end = data+size;
  1934 
  1935 	test_Equal(BTrace::EThreadIdentification,data[BTrace::ECategoryIndex]);
  1936 	test_Equal(BTrace::ENanoThreadDestroy ,data[BTrace::ESubCategoryIndex]);
  1937 	test_Equal(threadTraceId, Body(data)[0]);
  1938 	data=BTrace::NextRecord(data);
  1939 	test_Compare(data, < ,end);
  1940 
  1941 	test_Equal(BTrace::EThreadIdentification,data[BTrace::ECategoryIndex]);
  1942 	test_Equal(BTrace::EThreadDestroy ,data[BTrace::ESubCategoryIndex]);
  1943 	test_Equal(threadTraceId, Body(data)[0]);
  1944 	test_Equal(processTraceId, Body(data)[1]);
  1945 	test(threadId==Body(data)[2]);
  1946 	data=BTrace::NextRecord(data);
  1947 	test_Equal(data,end);
  1948 	Trace.DataUsed();
  1949 
  1950 	test.Next(_L("Cleanup after tests"));
  1951 	Trace.SetFilter(BTrace::EThreadIdentification,0);
  1952 	Trace.SetMode(0);
  1953 	r = Trace.ResizeBuffer(oldSize);
  1954 	test_KErrNone(r);
  1955 
  1956 	test.End();
  1957 	}
  1958 
  1959 
  1960 //---------------------------------------------
  1961 //! @SYMTestCaseID KBASE-T_BTRACE-0065
  1962 //! @SYMTestType UT
  1963 //! @SYMPREQ PREQ1030
  1964 //! @SYMTestCaseDesc Test BTrace category ECpuUsage.
  1965 //! @SYMTestActions Enable the ECpuUsage trace category for one second, then obtain captured
  1966 //!		traces using RBTrace.
  1967 //! @SYMTestExpectedResults Traces are generated for the sub-categories EIrqStart, EIDFCStart,
  1968 //!		EIDFCEnd and ENewThreadContext. The later must include the context ID of the main test
  1969 //!		program thread.
  1970 //! @SYMTestPriority High
  1971 //! @SYMTestStatus Implemented
  1972 //---------------------------------------------
  1973 void TestCpuUsage()
  1974 	{
  1975 	if(KErrNotSupported==Trace.Filter(BTrace::ECpuUsage))
  1976 		{
  1977 		test.Start(_L("Trace category not supported by this build of kernel."));
  1978 		test.End();
  1979 		return;
  1980 		}
  1981 
  1982 	test.Start(_L("Reset trace buffer"));
  1983 	Trace.SetMode(0);
  1984 	TInt oldSize = Trace.BufferSize();
  1985 	TInt r = Trace.ResizeBuffer(0x100000);
  1986 	test_KErrNone(r);
  1987 	Trace.SetMode(RBTrace::EEnable);
  1988 
  1989 	test.Next(_L("Generate traces for a short time..."));
  1990 	Trace.SetFilter(BTrace::ECpuUsage,1);
  1991 	User::After(1000*1000);
  1992 	Trace.SetFilter(BTrace::ECpuUsage,0);
  1993 
  1994 	test.Next(_L("Process traces"));
  1995 	TUint8 subCategories[256] = {0};
  1996 	TUint8* data;
  1997 	TInt size;
  1998 	while((size=Trace.GetData(data))!=0)
  1999 		{
  2000 		TUint8* end = data+size;
  2001 		for( ; data<end; data=BTrace::NextRecord(data))
  2002 			{
  2003 			test_Equal(BTrace::ECpuUsage,data[BTrace::ECategoryIndex]);
  2004 			TUint subCategory = data[BTrace::ESubCategoryIndex];
  2005 			TUint8* context = data+ContextOffset(data);
  2006 			TUint8* recordEnd = BTrace::NextRecord(data);
  2007 			if(subCategory==BTrace::ENewThreadContext)
  2008 				{
  2009 				test_Equal(context+4, recordEnd); // trace record should end after context data
  2010 				if(*(TUint32*)context != MainThreadTraceId)
  2011 					continue; // not a context switch to this thread
  2012 				}
  2013 			else if (subCategory==BTrace::EIrqStart || subCategory==BTrace::EFiqStart)
  2014 				{
  2015 				// may or may not contain vector number
  2016 				if (recordEnd != context)
  2017 					{
  2018 					test_Equal(context+4, recordEnd);
  2019 					}
  2020 				}
  2021 			else
  2022 				{
  2023 				test_Equal(context, recordEnd); // trace record should have no context or any data after
  2024 				}
  2025 			subCategories[subCategory] = 1; // set flag to say we've seen this kind of trace
  2026 			}
  2027 		Trace.DataUsed();
  2028 		}
  2029 
  2030 	test.Next(_L("Check for expected traces"));
  2031 	// timer interrupts should have generated IRQ traces...
  2032 	test(subCategories[BTrace::EIrqStart]);
  2033 	 // User::After should have caused timer interrupt to queue a DFC...
  2034 	test(subCategories[BTrace::EIDFCStart]);
  2035 	test(subCategories[BTrace::EIDFCEnd]);
  2036 	// Current thread must have got scheduled again...
  2037 	test(subCategories[BTrace::ENewThreadContext]);
  2038 
  2039 	test.Next(_L("Cleanup after tests"));
  2040 	Trace.SetFilter(BTrace::ECpuUsage,0);
  2041 	Trace.SetMode(0);
  2042 	r = Trace.ResizeBuffer(oldSize);
  2043 	test_KErrNone(r);
  2044 
  2045 	test.End();
  2046 	}
  2047 
  2048 
  2049 volatile TBool SoakDone = EFalse; // always false, but stops compiler warnings in SoakThreadFunction
  2050 
  2051 RThread SoakThread[4];
  2052 
  2053 TInt SoakThreadFunction(TAny* aData)
  2054 	{
  2055 	TUint32 random = 0;
  2056 	BTrace::TCategory category = (BTrace::TCategory)*(TUint8*)aData;
  2057 	TUint subCategory = 0;
  2058 	while(!SoakDone)
  2059 		{
  2060 		random = random*69069+1;
  2061 		TUint size = (random>>24u);
  2062 
  2063 		if(size<4)
  2064 			BTrace0(category,subCategory);
  2065 		else if(size<=8)
  2066 			BTrace4(category,subCategory,((TUint32*)aData)[1]);
  2067 		else if(size<12)
  2068 			BTrace8(category,subCategory,((TUint32*)aData)[1],((TUint32*)aData)[2]);
  2069 		else
  2070 			BTraceN(category,subCategory,((TUint32*)aData)[1],((TUint32*)aData)[2],&((TUint32*)aData)[3],size-12);
  2071 		++subCategory;
  2072 		}
  2073 	return 0;
  2074 	}
  2075 
  2076 
  2077 TInt SoakThreadFunction2(TAny* aData)
  2078 	{
  2079 	TUint32 random = 0;
  2080 	BTrace::TCategory category = (BTrace::TCategory)*(TUint8*)aData;
  2081 	TUint subCategory = 0;
  2082 	while(!SoakDone)
  2083 		{
  2084 		random = random*69069+1;
  2085 		TUint size = (random>>24u);
  2086 
  2087 		TInt outOk;
  2088 		if(size<=8)
  2089 			outOk = BTraceFiltered4(category,subCategory,((TUint32*)aData)[1]);
  2090 		else if(size<12)
  2091 			outOk = BTraceFiltered8(category,subCategory,((TUint32*)aData)[1],((TUint32*)aData)[2]);
  2092 		else
  2093 			outOk = BTraceFilteredN(category,subCategory,((TUint32*)aData)[1],((TUint32*)aData)[2],&((TUint32*)aData)[3],size-12);
  2094 		if(outOk)
  2095 			++subCategory;
  2096 		}
  2097 	return 0;
  2098 	}
  2099 
  2100 
  2101 TInt SoakControlThreadFunction(TAny*)
  2102 	{
  2103 	// randomly mess with thread priorities of soak test threads so
  2104 	// we get lots of preemption going on
  2105 	const TThreadPriority priorities[] =
  2106 		{
  2107 		EPriorityMuchLess,
  2108 		EPriorityLess,
  2109 		EPriorityNormal,
  2110 		EPriorityMore
  2111 		};
  2112 
  2113 	TUint32 random = 0;
  2114 	while(!SoakDone)
  2115 		{
  2116 		User::AfterHighRes(1);
  2117 		random = random*69069+1;
  2118 		SoakThread[(random>>16)%3].SetPriority(priorities[(random>>14)&3]);
  2119 		}
  2120 	return 0;
  2121 	}
  2122 
  2123 
  2124 void ChangeSecondaryFilter()
  2125 	{
  2126 	// mess with secondary filter...
  2127 	static TUint32 random = 0;
  2128 	random = random*69069+1;
  2129 	switch(random>>29)
  2130 		{
  2131 		case 0:
  2132 			Trace.SetFilter2(KBTraceFilterTestUid1,0);
  2133 			break;
  2134 		case 1:
  2135 			Trace.SetFilter2(KBTraceFilterTestUid1,1);
  2136 			break;
  2137 		case 2:
  2138 			Trace.SetFilter2(KBTraceFilterTestUid2,0);
  2139 			break;
  2140 		case 3:
  2141 			Trace.SetFilter2(KBTraceFilterTestUid2,1);
  2142 			break;
  2143 		case 4:
  2144 			Trace.SetFilter2(0);
  2145 			break;
  2146 		case 5:
  2147 			Trace.SetFilter2(1);
  2148 			break;
  2149 		case 6:
  2150 			Trace.SetFilter2(&KBTraceFilterTestUid1,1);
  2151 			break;
  2152 		case 7:
  2153 			Trace.SetFilter2(&KBTraceFilterTestUid2,1);
  2154 			break;
  2155 		}
  2156 	}
  2157 
  2158 //---------------------------------------------
  2159 //! @SYMTestCaseID KBASE-T_BTRACE-0066
  2160 //! @SYMTestType UT
  2161 //! @SYMPREQ PREQ1030
  2162 //! @SYMTestCaseDesc Soak tests
  2163 //! @SYMTestActions Generate ordered traces of random size using two worker threads and
  2164 //!		read the generated trace in the main test program thread. All threads are scheduled
  2165 //!		in a random manner.
  2166 //! @SYMTestExpectedResults Captured traces must contain the correct data and any
  2167 //!		missing traces must be indicated by the EMissingRecord flag in the next trace.
  2168 //! @SYMTestPriority High
  2169 //! @SYMTestStatus Implemented
  2170 //---------------------------------------------
  2171 void TestSoak(TUint aMode,TUint aTimeInSeconds)
  2172 	{
  2173 	aMode |= RBTrace::EEnable;
  2174 
  2175 	test.Start(_L("Reset trace buffer"));
  2176 	TInt oldSize = Trace.BufferSize();
  2177 	TInt r = Trace.ResizeBuffer(0x10000);
  2178 	test_KErrNone(r);
  2179 	Trace.SetMode(aMode);
  2180 	Trace.SetFilter(BTrace::ETest1,1);
  2181 	Trace.SetFilter(BTrace::ETest2,1);
  2182 	Trace.SetFilter2(KBTraceFilterTestUid2,1);
  2183 
  2184 	TUint32* buffer = (TUint32*)Trace.DataChunk().Base();
  2185 	test.Printf(_L("Buffer=%x %x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n"),buffer,
  2186 		buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7],buffer[8],buffer[9]);
  2187 
  2188 	test.Next(_L("Random traces..."));
  2189 	Trace1Sequence = 0;
  2190 	Trace2Sequence = 0;
  2191 	RTimer timer;
  2192 	test_KErrNone(timer.CreateLocal());
  2193 	SoakThread[0].Duplicate(RThread(),EOwnerProcess);
  2194 	test_KErrNone(SoakThread[1].Create(KNullDesC,SoakThreadFunction,0x1000,&User::Allocator(),KTestTrace1));
  2195 	test_KErrNone(SoakThread[2].Create(KNullDesC,SoakThreadFunction2,0x1000,&User::Allocator(),KTestTrace2));
  2196 	test_KErrNone(SoakThread[3].Create(KNullDesC,SoakControlThreadFunction,0x1000,&User::Allocator(),KTestTrace2));
  2197 	// The control thread must be resumed first otherwise time slicing perculiarities
  2198 	// can cause the soak threads to take all of the CPU time...
  2199 	SoakThread[3].SetPriority(EPriorityMuchMore);
  2200 	SoakThread[3].Resume();
  2201 
  2202 	TRequestStatus s;
  2203 	TTimeIntervalMicroSeconds32 tickPeriod;
  2204 	UserHal::TickPeriod(tickPeriod);
  2205 	TInt64 ticks = aTimeInSeconds;
  2206 	ticks *= 1000000;
  2207 	ticks /= tickPeriod.Int();
  2208 	timer.AfterTicks(s,(TInt)ticks);
  2209 
  2210 	// resume threads producing trace output...
  2211 	SoakThread[1].Resume();
  2212 	SoakThread[2].Resume();
  2213 
  2214 	TInt64 totalSize = 0;
  2215 	for(;;)
  2216 		{
  2217 		ChangeSecondaryFilter();
  2218 		const TInt KTraceDataBlockSize = 0x1000;
  2219 		TUint8* data;
  2220 		TInt size;
  2221 		while(s==KRequestPending && (size=Trace.GetData(data))!=0)
  2222 			{
  2223 //			RDebug::Printf("READ: data=%08x size=%08x\n",data,size);
  2224 			if(s!=KRequestPending)
  2225 				break;
  2226 			CheckTraceData(data,size);
  2227 			totalSize += size;
  2228 			Trace.DataUsed();
  2229 			}
  2230 		if(s!=KRequestPending)
  2231 			break;
  2232 		TRequestStatus waitStatus;
  2233 		Trace.RequestData(waitStatus,KTraceDataBlockSize);
  2234 		User::WaitForRequest(waitStatus);
  2235 		test_KErrNone(waitStatus.Int());
  2236 		}
  2237 	User::WaitForRequest(s);
  2238 	test_Equal(EExitPending, SoakThread[1].ExitType() );
  2239 	test_Equal(EExitPending, SoakThread[2].ExitType() );
  2240 	test_Equal(EExitPending, SoakThread[3].ExitType() );
  2241 	SoakThread[1].Kill(0);
  2242 	SoakThread[2].Kill(0);
  2243 	SoakThread[3].Kill(0);
  2244 	SoakThread[1].Close();
  2245 	SoakThread[2].Close();
  2246 	SoakThread[3].Close();
  2247 
  2248 	test.Printf(_L("total trace data processed = %ld k\n"),totalSize>>10);
  2249 
  2250 	test.Next(_L("Restore buffer"));
  2251 	r = Trace.ResizeBuffer(oldSize);
  2252 	test_KErrNone(r);
  2253 
  2254 	test.End();
  2255 	}
  2256 
  2257 
  2258 void KernelBenchmark(TUint& aTime1,TUint& aTime2,TUint& aTime3,TBool aTraceEnabled,TBool aFilter2)
  2259 	{
  2260 	TInt oldSize = Trace.BufferSize();
  2261 
  2262 	TInt r = Trace.ResizeBuffer(0x1000);
  2263 	test_KErrNone(r);
  2264 	Trace.SetMode(RBTrace::EFreeRunning|RBTrace::EEnable);
  2265 
  2266 	if(aFilter2)
  2267 		r = 1+TraceTest.TestBenchmark2(0,1000000);
  2268 	else
  2269 		r = 1+TraceTest.TestBenchmark(0,1000000);
  2270 	TUint8* data;
  2271 	TInt size = Trace.GetData(data);
  2272 	test(aTraceEnabled ? size!=0 : size==0);
  2273 	Trace.DataUsed();
  2274 	aTime1 = 1000000000/r;
  2275 
  2276 	r = Trace.ResizeBuffer(0x1000);
  2277 	test_KErrNone(r);
  2278 	Trace.SetMode(RBTrace::EFreeRunning|RBTrace::EEnable);
  2279 
  2280 	if(aFilter2)
  2281 		r = 1+TraceTest.TestBenchmark2(KMaxBTraceDataArray,1000000);
  2282 	else
  2283 		r = 1+TraceTest.TestBenchmark(KMaxBTraceDataArray,1000000);
  2284 	size = Trace.GetData(data);
  2285 	test(aTraceEnabled ? size!=0 : size==0);
  2286 	Trace.DataUsed();
  2287 	aTime2 = 1000000000/r;
  2288 
  2289 	r = 1+TraceTest.TestBenchmarkCheckFilter(aFilter2,1000000);
  2290 	aTime3 = 1000000000/r;
  2291 
  2292 	r = Trace.ResizeBuffer(oldSize);
  2293 	test_KErrNone(r);
  2294 	}
  2295 
  2296 
  2297 void UserBenchmark(TUint& aTime1,TUint& aTime2,TUint& aTime3,TBool aTraceEnabled,TBool aFilter2)
  2298 	{
  2299 	TInt oldSize = Trace.BufferSize();
  2300 
  2301 	RTimer timer;
  2302 	TRequestStatus status;
  2303 	test_KErrNone(timer.CreateLocal());
  2304 
  2305 	TInt r = Trace.ResizeBuffer(0x1000);
  2306 	test_KErrNone(r);
  2307 	Trace.SetMode(RBTrace::EFreeRunning|RBTrace::EEnable);
  2308 
  2309 	timer.After(status,1);
  2310 	User::WaitForRequest(status);
  2311 	timer.After(status,1000000);
  2312 	r = 0;
  2313 	if(aFilter2)
  2314 		do
  2315 			{
  2316 			BTraceFiltered4(BTrace::ETest1,0,KBTraceFilterTestUid1);
  2317 			++r;
  2318 			}
  2319 		while(status==KRequestPending);
  2320 	else
  2321 		do
  2322 			{
  2323 			BTrace0(BTrace::ETest1,0);
  2324 			++r;
  2325 			}
  2326 		while(status==KRequestPending);
  2327 	User::WaitForRequest(status);
  2328 	TUint8* data;
  2329 	TInt size = Trace.GetData(data);
  2330 	test(aTraceEnabled ? size!=0 : size==0);
  2331 	Trace.DataUsed();
  2332 	aTime1 = 1000000000/r;
  2333 
  2334 	r = Trace.ResizeBuffer(0x1000);
  2335 	test_KErrNone(r);
  2336 	Trace.SetMode(RBTrace::EFreeRunning|RBTrace::EEnable);
  2337 
  2338 	timer.After(status,1);
  2339 	User::WaitForRequest(status);
  2340 	timer.After(status,1000000);
  2341 	r = 0;
  2342 	if(aFilter2)
  2343 		do
  2344 			{
  2345 			BTraceFilteredContextN(BTrace::ETest1,0,KBTraceFilterTestUid1,0,KTestTrace1,KMaxBTraceDataArray);
  2346 			++r;
  2347 			}
  2348 		while(status==KRequestPending);
  2349 	else
  2350 		do
  2351 			{
  2352 			BTraceContextN(BTrace::ETest1,0,0,0,KTestTrace1,KMaxBTraceDataArray);
  2353 			++r;
  2354 			}
  2355 		while(status==KRequestPending);
  2356 	User::WaitForRequest(status);
  2357 	size = Trace.GetData(data);
  2358 	test(aTraceEnabled ? size!=0 : size==0);
  2359 	Trace.DataUsed();
  2360 	aTime2 = 1000000000/r;
  2361 
  2362 	timer.After(status,1);
  2363 	User::WaitForRequest(status);
  2364 	timer.After(status,1000000);
  2365 	r = 0;
  2366 	TBool check = -1;
  2367 	if(aFilter2)
  2368 		do
  2369 			{
  2370 			check = BTrace::CheckFilter2(BTrace::ETest1,KBTraceFilterTestUid1);
  2371 			++r;
  2372 			}
  2373 		while(status==KRequestPending);
  2374 	else
  2375 		do
  2376 			{
  2377 			check = BTrace::CheckFilter(BTrace::ETest1);
  2378 			++r;
  2379 			}
  2380 		while(status==KRequestPending);
  2381 	test(check == aTraceEnabled);
  2382 	aTime3 = 1000000000/r;
  2383 
  2384 	r = Trace.ResizeBuffer(oldSize);
  2385 	test_KErrNone(r);
  2386 	}
  2387 
  2388 
  2389 //---------------------------------------------
  2390 //! @SYMTestCaseID KBASE-T_BTRACE-0066-0067
  2391 //! @SYMTestType UT
  2392 //! @SYMPREQ PREQ1030
  2393 //! @SYMTestCaseDesc Benchmark tracing.
  2394 //! @SYMTestActions Time the generation of minimum and maximum sized traces both with
  2395 //!		and without the trace filter enabled for the trace category.
  2396 //! @SYMTestExpectedResults Trace time with filter enabled should not excede 2000 nano-seconds,
  2397 //!		and time with filter disabled should not excede 500 nano-seconds. (These limits are not
  2398 //!		asserted). If time significantly excedes this then detailed investigation is required.
  2399 //! @SYMTestPriority Medium
  2400 //! @SYMTestStatus Implemented
  2401 //---------------------------------------------
  2402 void TestBenchmark(TBool aUserTrace)
  2403 	{
  2404 	TUint t1 = 0;
  2405 	TUint t2 = 0;
  2406 	TUint t3 = 0;
  2407 
  2408 #define BENCH(a1,a2) aUserTrace ? UserBenchmark(t1,t2,t3,a1,a2) : KernelBenchmark(t1,t2,t3,a1,a2)
  2409 
  2410 	test.Printf(_L("                                      Min Trace   Max Trace      Filter\n"));
  2411 
  2412 	Trace.SetFilter(BTrace::ETest1,0);
  2413 	BENCH(0,0);
  2414 	test.Printf(_L("filter1 off                           %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  2415 
  2416 	Trace.SetFilter(BTrace::ETest1,1);
  2417 	BENCH(1,0);
  2418 	test.Printf(_L("filter1 on                            %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  2419 
  2420 	Trace.SetFilter(BTrace::ETest1,0);
  2421 	Trace.SetFilter2(0);
  2422 	BENCH(0,1);
  2423 	test.Printf(_L("filter1 off   filter2 off             %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  2424 
  2425 	Trace.SetFilter(BTrace::ETest1,1);
  2426 	Trace.SetFilter2(0);
  2427 	BENCH(0,1);
  2428 	test.Printf(_L("filter1 on    global filter2 off      %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  2429 
  2430 	Trace.SetFilter2(1);
  2431 	BENCH(1,1);
  2432 	test.Printf(_L("filter1 on    global filter2 on       %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  2433 
  2434 	Trace.SetFilter2(&KBTraceFilterTestUid2,1);
  2435 	BENCH(0,1);
  2436 	test.Printf(_L("filter1 on    1 UID filter2 off       %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  2437 
  2438 	Trace.SetFilter2(&KBTraceFilterTestUid1,1);
  2439 	BENCH(1,1);
  2440 	test.Printf(_L("filter1 on    1 UID filter2 on        %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  2441 
  2442 	Trace.SetFilter2(BigFilter2,sizeof(BigFilter2)/sizeof(TUint32));
  2443 	Trace.SetFilter2(KBTraceFilterTestUid1,0);
  2444 	BENCH(0,1);
  2445 	test.Printf(_L("filter1 on    100 UID filter2 off     %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  2446 
  2447 	Trace.SetFilter2(BigFilter2,sizeof(BigFilter2)/sizeof(TUint32));
  2448 	BENCH(1,1);
  2449 	test.Printf(_L("filter1 on    100 UID filter2 on      %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  2450 
  2451 	Trace.SetFilter(BTrace::ETest1,0);
  2452 	Trace.SetFilter2(0);
  2453 	}
  2454 
  2455 struct THREADTRACETESTSTRUCT {
  2456 	TInt* alloc_addr;
  2457 	void* chunk_addr;
  2458 };
  2459 
  2460 LOCAL_D TInt threadtraceTestThread(TAny* param)
  2461 	{
  2462 	THREADTRACETESTSTRUCT* p = (THREADTRACETESTSTRUCT*)param;
  2463 	p->alloc_addr = new TInt;
  2464 	delete p->alloc_addr;
  2465 	return 0;
  2466 	}
  2467 
  2468 void TestHeapAndChunkTrace()
  2469 	{
  2470 	if(KErrNotSupported==Trace.Filter(BTrace::EHeap))
  2471 		{
  2472 		test.Start(_L("Trace category EHeap not supported by this build of kernel."));
  2473 		test.End();
  2474 		return;
  2475 		}
  2476 
  2477 	test.Start(_L("Reset trace buffer"));
  2478 	Trace.SetMode(0);
  2479 	TInt oldSize = Trace.BufferSize();
  2480 	TInt r = Trace.ResizeBuffer(0x100000);
  2481 	test_KErrNone(r);
  2482 	Trace.SetFilter(BTrace::EHeap,0);
  2483 	Trace.SetFilter(BTrace::EChunks,0);
  2484 	Trace.SetMode(RBTrace::EEnable);
  2485 
  2486 	test.Next(_L("Test heap-alloc works as expected"));
  2487 	Trace.SetFilter(BTrace::EHeap,1);
  2488 	TBool chunkTraceEnabled = Trace.SetFilter(BTrace::EChunks,1)!=KErrNotSupported;
  2489 
  2490 	// Create a test thread
  2491 	THREADTRACETESTSTRUCT threadtest;
  2492 	RThread thread;
  2493 	TRequestStatus stat;
  2494 	test.Next(_L("Test thread creation heap trace"));
  2495 	r=thread.Create(_L("t_tbrace_2"),threadtraceTestThread,KDefaultStackSize,0x2000,0x2000,&threadtest);
  2496 	test_KErrNone(r);
  2497 	thread.Logon(stat);
  2498 	thread.Resume();
  2499 	User::WaitForRequest(stat);
  2500 
  2501 
  2502 	// search for heap records in trace...
  2503 	TUint8* data;
  2504 	TUint8* trace;
  2505 	TInt size=Trace.GetData(trace);
  2506 	test_NotNull(size);
  2507 	TUint8* end = trace+size;
  2508 	TUint chunk_ptr = 0, heap_chunk_ptr = 0;
  2509 	int found_chunk_create = 0;
  2510 	int found_heap_chunk_create = 0;
  2511 	int found_heap_create=0;
  2512 	int found_heap_alloc=0;
  2513 	int found_heap_free=0;
  2514 	for(data=trace; data<end; data=BTrace::NextRecord(data))
  2515 		{
  2516 		if(data[BTrace::ECategoryIndex]==BTrace::EChunks)
  2517 			{
  2518 			if(data[BTrace::ESubCategoryIndex]==BTrace::EChunkCreated)
  2519 				{
  2520 				found_chunk_create=1;
  2521 				chunk_ptr = Body(data)[0];
  2522 				}
  2523 			}
  2524 		if(data[BTrace::ECategoryIndex]==BTrace::EHeap)
  2525 			{
  2526 			if(data[BTrace::ESubCategoryIndex]==BTrace::EHeapCreate)
  2527 				found_heap_create=1;
  2528 			if(data[BTrace::ESubCategoryIndex]==BTrace::EHeapChunkCreate)
  2529 				{
  2530 				found_heap_chunk_create=1;
  2531 				heap_chunk_ptr = Body(data)[1];
  2532 				}
  2533 			if(data[BTrace::ESubCategoryIndex]==BTrace::EHeapAlloc)
  2534 				{
  2535 				if(Body(data)[1]==(TUint)threadtest.alloc_addr)
  2536 					{
  2537 					found_heap_alloc=1;
  2538 					test_Equal(4, Body(data)[2]);
  2539 					test_Compare(Body(data)[3], >= ,4);
  2540 					}
  2541 				}
  2542 			if(data[BTrace::ESubCategoryIndex]==BTrace::EHeapFree)
  2543 				{
  2544 				if(Body(data)[1]==(TUint)threadtest.alloc_addr)
  2545 					found_heap_free=1;
  2546 				}
  2547 			}
  2548 		}
  2549 	test(found_heap_create);
  2550 	test(found_heap_chunk_create);
  2551 	test(found_heap_alloc);
  2552 	test(found_heap_free);
  2553 	if(!chunkTraceEnabled)
  2554 		{
  2555 		test.Next(_L("Trace category EChunk not supported by this build of kernel."));
  2556 		test.End();
  2557 		return;
  2558 		}
  2559 	test(chunk_ptr && heap_chunk_ptr);
  2560 	test(chunk_ptr == heap_chunk_ptr);
  2561 	//Trace.DataUsed();
  2562 
  2563 	// Turn on chunk trace and empty btrace buffer
  2564 	test.Next(_L("Chunk testing"));
  2565 	Trace.SetFilter(BTrace::EChunks,1);
  2566 	Trace.Empty();
  2567 
  2568 	// Create a chunk and test the expected traces
  2569 	RChunk chunk;
  2570 	test_KErrNone(chunk.CreateLocal(4096, 4*1024*1024));
  2571 	trace = NULL;
  2572 	size=Trace.GetData(trace);
  2573 	test_NotNull(size);
  2574 	end = trace+size;
  2575 	found_chunk_create=0;
  2576 	for(data=trace; data<end; data=BTrace::NextRecord(data))
  2577 		{
  2578 		if(data[BTrace::ECategoryIndex]==BTrace::EChunks)
  2579 			{
  2580 			if(data[BTrace::ESubCategoryIndex]==BTrace::EChunkCreated)
  2581 				{
  2582 				test_Equal(4*1024*1024, Body(data)[1]);
  2583 				found_chunk_create = 1;
  2584 				}
  2585 			if(data[BTrace::ESubCategoryIndex]==BTrace::EChunkMemoryAllocated)
  2586 				{
  2587 				test_Equal(4096, Body(data)[2]);
  2588 				found_heap_alloc = 1;
  2589 				}
  2590 			}
  2591 		}
  2592 	test(found_heap_alloc && found_chunk_create);
  2593 	Trace.DataUsed();
  2594 
  2595 	test.Next(_L("Cleanup after tests"));
  2596 	Trace.SetFilter(BTrace::EHeap,0);
  2597 	Trace.SetMode(0);
  2598 	r = Trace.ResizeBuffer(oldSize);
  2599 	test_KErrNone(r);
  2600 
  2601 	test.End();
  2602 	}
  2603 
  2604 void SetBTraceFilter(const TUint32* aNew,TUint32* aOld)
  2605 	{
  2606 	TUint category = 0;
  2607 	do
  2608 		{
  2609 		TUint32 newBits = *aNew++;
  2610 		TUint32 oldBits = 0;
  2611 		do
  2612 			{
  2613 			oldBits >>= 1;
  2614 			if(Trace.SetFilter(category,newBits&1))
  2615 				oldBits |= 0x80000000u;
  2616 			newBits >>= 1;
  2617 			++category;
  2618 			}
  2619 		while(category&31);
  2620 		if(aOld)
  2621 			*aOld++ = oldBits;
  2622 		}
  2623 	while(category<256);
  2624 	}
  2625 
  2626 
  2627 TUint32 OldTraceFilter[8] = {0};
  2628 
  2629 
  2630 //thread function to generate BTrace::EHeap::EHeapAllocFail event
  2631 LOCAL_D TInt ThreadtraceAllocFailTestThread(TAny* /*param*/)
  2632   	{
  2633   	RPointerArray<TInt32> array(1000);
  2634   	TInt i = 1;
  2635   	for(;;)
  2636   		{
  2637   		TInt32* p = new TInt32[(++i)*2];
  2638   		if(!p)
  2639   			break;
  2640   		else
  2641   			if(array.Append(p) == KErrNoMemory)
  2642   				break;
  2643   		}
  2644   	array.ResetAndDestroy();
  2645   	array.Close();
  2646   	return 0;
  2647   	}
  2648 
  2649 //thread function to generate BTrace::EHeap::EHeapReAllocFail event
  2650 LOCAL_D TInt ThreadtraceReAllocFailTestThread(TAny* /*param*/)
  2651 	{
  2652 	TInt s = 4;
  2653 	TUint8 *p = (TUint8*)User::Alloc(s);
  2654 	for(;;)
  2655 		{
  2656 		s *= 2;
  2657 		TUint8* np = (TUint8*)User::ReAlloc(p, s);
  2658 		if(!np)
  2659 			{
  2660 			delete [] p;
  2661 			break;
  2662 			}
  2663 		else
  2664 			p=np;
  2665 		}
  2666 	return 0;
  2667 	}
  2668 
  2669 
  2670 
  2671 //---------------------------------------------------------------------------------------------------------------------
  2672 //! @SYMTestCaseID				KBASE-T_BTRACE-0733
  2673 //! @SYMTestCaseDesc			Test BTrace - EHeapAllocFail and EHeapReAllocFail subcategories.
  2674 //! @SYMTestType				UT
  2675 //! @SYMPREQ					PREQ1340
  2676 //! @SYMTestPriority			Medium
  2677 //! @SYMTestActions
  2678 //! 	1.	Configure BTrace to use EHeap and EThreadIdentification as main filter
  2679 //!			categories.
  2680 //! 	2.	Create and start a thread which will eventually exhaust
  2681 //!			all memory resources (this should result with sending a trace
  2682 //!			from allocator class - sent trace should have
  2683 //!			category - EHeap and subcategory - EHeapAllocFail).
  2684 //! 	3.	After thread (from previous point) crashes, get trace data from BTrace
  2685 //!			and search for trace with category EHeap and subcategory EHeapAllocFail
  2686 //!		4.	Validate trace data payload - it should have exactly 8 bytes (2x4 bytes values).
  2687 //!
  2688 //! @SYMTestExpectedResults
  2689 //! 	1.	Trace data should contain at least one trace with category
  2690 //!			EHeap and subcategory EHeapAllocFail.
  2691 //! 	2.	Trace data payload (where category is EHeap and subcategory is EHeapAllocFail) should
  2692 //!			be 8 bytes long (2 x 4 bytes values).
  2693 //---------------------------------------------------------------------------------------------------------------------
  2694 void TestHeapAllocFailEvent(TInt aTestCategory)
  2695 	{
  2696 	//configurnig trace
  2697 	if(aTestCategory == BTrace::EHeapAllocFail)
  2698 		test.Next(_L("Test to check BTrace::EHeap::EHeapAllocFail trace event"));
  2699 	else if(aTestCategory == BTrace::EHeapReAllocFail)
  2700 		test.Next(_L("Test to check BTrace::EHeap::EHeapReAllocFail trace event"));
  2701 	//configure BTrace
  2702 	Trace.Open();
  2703 	Trace.SetMode(0);
  2704 	TInt r = Trace.ResizeBuffer(0x100000);
  2705 
  2706 	test_KErrNone(r);
  2707 	Trace.SetFilter(BTrace::EHeap,0);
  2708 	Trace.SetFilter(BTrace::EChunks,0);
  2709 	Trace.SetMode(RBTrace::EEnable);
  2710 	Trace.SetFilter(BTrace::EHeap,1);
  2711 	Trace.SetFilter(BTrace::EThreadIdentification,1);
  2712 
  2713 	//start thread to cause EHeapAllocFail event
  2714 	RThread thread;
  2715 	TRequestStatus stat;
  2716 
  2717 	//starting test thread
  2718 	if(aTestCategory == BTrace::EHeapAllocFail)
  2719 		r = thread.Create(_L("t_btrace_allocfail_thread"), ThreadtraceAllocFailTestThread, KDefaultStackSize, 0x2000, 0x2000, NULL);
  2720 	else if(aTestCategory == BTrace::EHeapReAllocFail)
  2721 		r = thread.Create(_L("t_btrace_reallocfail_thread"), ThreadtraceReAllocFailTestThread, KDefaultStackSize, 0x2000, 0x2000, NULL);
  2722 
  2723 	test_KErrNone(r);
  2724 	thread.Logon(stat);
  2725 	thread.Resume();
  2726 	User::WaitForRequest(stat);
  2727 	thread.Close();
  2728 
  2729 	//getting trace data
  2730 	TUint8* data;
  2731 	TUint8* trace;
  2732 	TInt size=Trace.GetData(trace);
  2733 
  2734 	test_NotNull(size);
  2735 	TUint8* end = trace+size;
  2736 	TInt8 found_heap_allocfail = 0;
  2737 
  2738 	TInt subCat = BTrace::EHeapAllocFail;
  2739 	TInt expectedDataSize = 8;
  2740 	if(aTestCategory == BTrace::EHeapReAllocFail)
  2741 		{
  2742 		subCat = BTrace::EHeapReAllocFail;
  2743 		expectedDataSize = 12;
  2744 		}
  2745 
  2746 	for(data=trace; data<end; data=BTrace::NextRecord(data))
  2747 		{
  2748 		if(data[BTrace::ECategoryIndex]==BTrace::EHeap)
  2749 			if(data[BTrace::ESubCategoryIndex]==subCat)
  2750 				{
  2751 				found_heap_allocfail = 1;
  2752 				TInt allocfail_data_size = ((TInt)data[BTrace::ESizeIndex]) - ExtraSize(data);
  2753 				test_Equal(allocfail_data_size,expectedDataSize);
  2754 				break; //we're looking only for one record
  2755 				}
  2756 		}
  2757 	test(found_heap_allocfail);
  2758 
  2759 	//closing trace
  2760 	Trace.DataUsed();
  2761 	Trace.Empty();
  2762 	Trace.SetMode(0);
  2763 	Trace.Close();
  2764 	}
  2765 
  2766 
  2767 bool FindHeapCorruptionTrace(TUint8* aData, TInt aSize, TInt& aFoundSize)
  2768 	{
  2769 	TUint8* end = aData+aSize;
  2770 	TUint8* data;
  2771 	for(data=aData; data<end; data=BTrace::NextRecord(data))
  2772 		{
  2773 		if(data[BTrace::ECategoryIndex] == BTrace::EHeap)
  2774 			if(data[BTrace::ESubCategoryIndex] == BTrace::EHeapCorruption)
  2775 				{
  2776 				aFoundSize = data[BTrace::ESizeIndex] - ExtraSize(data);
  2777 				return true;
  2778 				}
  2779 		}
  2780 	return false;
  2781 	}
  2782 
  2783 
  2784 //---------------------------------------------------------------------------------------------------------------------
  2785 //! @SYMTestCaseID				KBASE-T_BTRACE-0734
  2786 //! @SYMTestCaseDesc			Test BTrace - EHeapCorruption subcategory.
  2787 //! @SYMTestType				UT
  2788 //! @SYMPREQ					PREQ1340
  2789 //! @SYMTestPriority			Medium
  2790 //! @SYMTestActions
  2791 //! 	1.	Configure BTrace to use EHeap and EThreadIdentification categories.
  2792 //! 	2.	Use test application (t_heapcorruption.exe) with parameters: 1, 2, 3 or 4 to
  2793 //!			to corrupt heap memory (for this application)
  2794 //! 	3.	Get trace data from BTrace and search for trace with category EHeap and
  2795 //!			subcategory EHeapCorruption.
  2796 //!		4.	Validate payload size for found traces.
  2797 //!
  2798 //! @SYMTestExpectedResults
  2799 //! 	1.	Test application (when started with either argument) should generate at least
  2800 //!			one trace with category EHeap and subcategory EHeapCorruption.
  2801 //! 	2.	Trace data payload should be 12 bytes long (3x4 bytes values).
  2802 //---------------------------------------------------------------------------------------------------------------------
  2803 void TestHeapCorruptionEvents()
  2804 	{
  2805 	TInt r = KErrNone;
  2806 	test.Next(_L("Test to check BTrace::EHeap::EHeapCorruption trace events"));
  2807 	//configure BTrace
  2808 	Trace.Open();
  2809 	Trace.SetMode(0);
  2810 	Trace.ResizeBuffer(0x100000);
  2811 	test_KErrNone(r);
  2812 	Trace.SetFilter(BTrace::EHeap,0);
  2813 	Trace.SetFilter(BTrace::EChunks,0);
  2814 	Trace.SetMode(RBTrace::EEnable);
  2815 	Trace.SetFilter(BTrace::EHeap,1);
  2816 	Trace.SetFilter(BTrace::EThreadIdentification,1);
  2817 
  2818 	_LIT(KHeapCorrApp, "t_heapcorruption.exe");
  2819 	_LIT(KCorruption0, "0"); //RHeap:: corruption type (when EMonitorMemory flag is set)
  2820 	_LIT(KCorruption1, "1"); //RHeap::EBadFreeCellAddress corruption type
  2821 	_LIT(KCorruption2, "2"); //RHeap::EBadFreeCellSize corruption type
  2822 	_LIT(KCorruption3, "3"); //RHeap::EBadAllocatedCellSize corruption type
  2823 	_LIT(KCorruption4, "4"); //RHeap::EBadAllocatedCellAddress corruption type
  2824 	_LIT(KCorruptionSpecial1, "1000"); //RHeap::EBadAllocatedCellSize (with EMonitorMemory flag set)
  2825 	RProcess p;
  2826 	TInt e = KErrNone;
  2827 	TRequestStatus status;
  2828 	TUint8* trace;
  2829 	TInt size, payloadSize;
  2830 	bool res;
  2831 
  2832 	//test 0 (for memory monitoring tools - when EMonitorMemory heap flag is set)
  2833 	test.Printf(_L("test 0\n"));
  2834 	Trace.SetMode(RBTrace::EEnable);
  2835 	e = p.Create(KHeapCorrApp, KCorruption0);
  2836 	test_KErrNone(e);
  2837 	p.Resume();
  2838 	p.Logon(status);
  2839 	User::WaitForRequest(status);
  2840 	p.Close();
  2841 	size = Trace.GetData(trace);
  2842 	test_NotNull(size);
  2843 	res = FindHeapCorruptionTrace(trace, size, payloadSize);
  2844 	test(res==true);
  2845 	test(payloadSize == 12); //payload in this case must be 12 bytes long (3x4bytes)
  2846 	Trace.DataUsed();
  2847 	Trace.Empty();
  2848 	Trace.SetMode(0);
  2849 
  2850 	//test 1 -
  2851 	test.Printf(_L("test 1\n"));
  2852 	Trace.SetMode(RBTrace::EEnable);
  2853 	e = p.Create(KHeapCorrApp, KCorruption1);
  2854 	test_KErrNone(e);
  2855 	p.Resume();
  2856 	p.Logon(status);
  2857 	User::WaitForRequest(status);
  2858 	p.Close();
  2859 	size = Trace.GetData(trace);
  2860 	test_NotNull(size);
  2861 	res = FindHeapCorruptionTrace(trace, size, payloadSize);
  2862 	test(res==true);
  2863 	test(payloadSize == 12); //payload in this case must be 12 bytes long (3x4bytes)
  2864 	Trace.DataUsed();
  2865 	Trace.Empty();
  2866 	Trace.SetMode(0);
  2867 
  2868 	//test 2
  2869 	test.Printf(_L("test 2\n"));
  2870 	Trace.SetMode(RBTrace::EEnable);
  2871 	e = p.Create(KHeapCorrApp, KCorruption2);
  2872 	test_KErrNone(e);
  2873 	p.Resume();
  2874 	p.Logon(status);
  2875 	User::WaitForRequest(status);
  2876 	p.Close();
  2877 	size = Trace.GetData(trace);
  2878 	test_NotNull(size);
  2879 	res = FindHeapCorruptionTrace(trace, size, payloadSize);
  2880 	test(res==true);
  2881 	test(payloadSize == 12); //payload in this case must be 12 bytes long (3x4bytes)
  2882 	Trace.DataUsed();
  2883 	Trace.Empty();
  2884 	Trace.SetMode(0);
  2885 
  2886 	//test 3
  2887 	test.Printf(_L("test 3\n"));
  2888 	Trace.SetMode(RBTrace::EEnable);
  2889 	e = p.Create(KHeapCorrApp, KCorruption3);
  2890 	test_KErrNone(e);
  2891 	p.Resume();
  2892 	p.Logon(status);
  2893 	User::WaitForRequest(status);
  2894 	p.Close();
  2895 	size = Trace.GetData(trace);
  2896 	test_NotNull(size);
  2897 	res = FindHeapCorruptionTrace(trace, size, payloadSize);
  2898 	test(res==true);
  2899 	test(payloadSize == 12); //payload in this case must be 12 bytes long (3x4bytes)
  2900 	Trace.DataUsed();
  2901 	Trace.Empty();
  2902 	Trace.SetMode(0);
  2903 
  2904 	//test 4
  2905 	test.Printf(_L("test 4\n"));
  2906 	Trace.SetMode(RBTrace::EEnable);
  2907 	e = p.Create(KHeapCorrApp, KCorruption4);
  2908 	test_KErrNone(e);
  2909 	p.Resume();
  2910 	p.Logon(status);
  2911 	User::WaitForRequest(status);
  2912 	p.Close();
  2913 	size = Trace.GetData(trace);
  2914 	test_NotNull(size);
  2915 	res = FindHeapCorruptionTrace(trace, size, payloadSize);
  2916 	test(res==true);
  2917 	test(payloadSize == 12); //payload in this case must be 12 bytes long (3x4bytes)
  2918 	Trace.DataUsed();
  2919 	Trace.Empty();
  2920 	Trace.SetMode(0);
  2921 
  2922 	//test 5 (test ____MEMORY_MONITOR_CHECK_CELL macro)
  2923 	test.Printf(_L("test 5\n"));
  2924 	Trace.SetMode(RBTrace::EEnable);
  2925 	e = p.Create(KHeapCorrApp, KCorruptionSpecial1);
  2926 	test_KErrNone(e);
  2927 	p.Resume();
  2928 	p.Logon(status);
  2929 	User::WaitForRequest(status);
  2930 	p.Close();
  2931 	size = Trace.GetData(trace);
  2932 	test_NotNull(size);
  2933 	res = FindHeapCorruptionTrace(trace, size, payloadSize);
  2934 	test(res==true);
  2935 	test(payloadSize == 12); //payload in this case must be 12 bytes long (3x4bytes)
  2936 	Trace.DataUsed();
  2937 	Trace.Empty();
  2938 	Trace.SetMode(0);
  2939 
  2940 	//closing trace
  2941 	Trace.DataUsed();
  2942 	Trace.Empty();
  2943 	Trace.SetMode(0);
  2944 	Trace.Close();
  2945 	}
  2946 
  2947 
  2948 //Set up utrace
  2949 TUint32 KUtracePcValues[3]={0, 0x123456, 0x987654};
  2950 
  2951 #define T_UTRACE_HEADER(aSize,aClassification,aContext,aPc)																\
  2952 	((((aSize) + (aContext?4:0) + (aPc?4:0)) << BTrace::ESizeIndex*8)										\
  2953 	+(((aContext?BTrace::EContextIdPresent:0) | (aPc?BTrace::EPcPresent:0)) << BTrace::EFlagsIndex*8)			\
  2954 	+((aClassification) << BTrace::ECategoryIndex*8)																				\
  2955 	+((KTest1SubCategory) << BTrace::ESubCategoryIndex*8))
  2956 
  2957 #define UTRACE_SECONDARY(aClassification,aModuleUid,aThreadIdPresent,aPcPresent,aPc,aFormatId)	\
  2958 	BTrace::OutFilteredPcFormatBig(T_UTRACE_HEADER(8,aClassification,aThreadIdPresent,aPcPresent),(TUint32)(aModuleUid),aPc,aFormatId,0,0)
  2959 
  2960 #define UTRACE_SECONDARY_4(aClassification,aModuleUid,aThreadIdPresent,aPcPresent,aPc,aFormatId, aData1) \
  2961 	BTrace::OutFilteredPcFormatBig(T_UTRACE_HEADER(8,aClassification,aThreadIdPresent,aPcPresent),(TUint32)(aModuleUid),aPc,aFormatId,&aData1,4)
  2962 
  2963 #define UTRACE_SECONDARY_ANY(aClassification, aModuleUid, aThreadIdPresent, aPcPresent, aPc, aFormatId, aData, aDataSize) \
  2964 	BTrace::OutFilteredPcFormatBig(T_UTRACE_HEADER(8,aClassification,aThreadIdPresent,aPcPresent),(TUint32)(aModuleUid),aPc,aFormatId,aData,(TInt)(aDataSize))
  2965 
  2966 void UTraceUserBenchmark(TUint& aTime1,TUint& aTime2,TUint& aTime3,TBool aTraceEnabled)
  2967 	{
  2968 	TInt oldSize = Trace.BufferSize();
  2969 
  2970 	RTimer timer;
  2971 	TRequestStatus status;
  2972 	test_KErrNone(timer.CreateLocal());
  2973 
  2974 	TInt r = Trace.ResizeBuffer(0x1000);
  2975 	test_KErrNone(r);
  2976 	Trace.SetMode(RBTrace::EFreeRunning|RBTrace::EEnable);
  2977 
  2978 	timer.After(status,1);
  2979 	User::WaitForRequest(status);
  2980 	timer.After(status,1000000);
  2981 	r = 0;
  2982 	TUint32* frm = (TUint32*)KTestTrace1;
  2983 	TUint16 formatId = (TUint16)frm[2];
  2984 
  2985 	do
  2986 		{
  2987 		UTRACE_SECONDARY(BTrace::ETest1,KBTraceFilterTestUid1,EFalse,EFalse,0,formatId);
  2988 		++r;
  2989 		}
  2990 	while(status==KRequestPending);
  2991 	User::WaitForRequest(status);
  2992 	TUint8* data;
  2993 	TInt size = Trace.GetData(data);
  2994 	test(aTraceEnabled ? size!=0 : size==0);
  2995 	Trace.DataUsed();
  2996 	aTime1 = 1000000000/r;
  2997 
  2998 	r = Trace.ResizeBuffer(0x1000);
  2999 	test_KErrNone(r);
  3000 	Trace.SetMode(RBTrace::EFreeRunning|RBTrace::EEnable);
  3001 
  3002 	timer.After(status,1);
  3003 	User::WaitForRequest(status);
  3004 	timer.After(status,1000000);
  3005 	r = 0;
  3006 	do
  3007 		{
  3008 		//BTraceFilteredContextN(BTrace::ETest1,0,KBTraceFilterTestUid1,0,KTestTrace1,KMaxBTraceDataArray);
  3009 		UTRACE_SECONDARY_ANY(BTrace::ETest1,KBTraceFilterTestUid1,ETrue,EFalse,0,formatId,KTestTrace1,KMaxBTraceDataArray);
  3010 		++r;
  3011 		}
  3012 	while(status==KRequestPending);
  3013 	User::WaitForRequest(status);
  3014 	size = Trace.GetData(data);
  3015 	test(aTraceEnabled ? size!=0 : size==0);
  3016 	Trace.DataUsed();
  3017 	aTime2 = 1000000000/r;
  3018 
  3019 	timer.After(status,1);
  3020 	User::WaitForRequest(status);
  3021 	timer.After(status,1000000);
  3022 	r = 0;
  3023 	TBool check = -1;
  3024 	do
  3025 		{
  3026 		check = BTrace::CheckFilter2(BTrace::ETest1,KBTraceFilterTestUid1);
  3027 		++r;
  3028 		}
  3029 	while(status==KRequestPending);
  3030 	test(check == aTraceEnabled);
  3031 	aTime3 = 1000000000/r;
  3032 
  3033 	r = Trace.ResizeBuffer(oldSize);
  3034 	test_KErrNone(r);
  3035 	}
  3036 
  3037 //---------------------------------------------
  3038 //! @SYMTestCaseID 		KBASE-T_BTRACE-2442
  3039 //! @SYMTestType 		UT
  3040 //! @SYMPREQ 			CR1623
  3041 //! @SYMTestCaseDesc 	Benchmark utracing.
  3042 //! @SYMTestActions 	Time the generation of minimum and maximum sized utraces both with
  3043 //!						and without the trace filter enabled for the trace category.
  3044 //! @SYMTestExpectedResults Trace time with filter enabled should not excede 2000 nano-seconds,
  3045 //!						and time with filter disabled should not excede 500 nano-seconds. (These limits are not
  3046 //!						asserted). If time significantly excedes this then detailed investigation is required.
  3047 //! @SYMTestPriority 	Medium
  3048 //! @SYMTestStatus 		Prototype
  3049 //---------------------------------------------
  3050 void TestUtraceBenchmark(TBool aUserTrace)
  3051 	{
  3052 	TUint t1 = 0;
  3053 	TUint t2 = 0;
  3054 	TUint t3 = 0;
  3055 //This uses btrace kernel benching atm, need to change once kernel is implemented
  3056 #define UBENCH(a1) aUserTrace ? UTraceUserBenchmark(t1,t2,t3,a1) : KernelBenchmark(t1,t2,t3,a1,1)
  3057 
  3058 	test.Printf(_L("                                      Min Trace   Max Trace      Filter\n"));
  3059 
  3060 	Trace.SetFilter(BTrace::ETest1,0);
  3061 	Trace.SetFilter2(0);
  3062 	UBENCH(0);
  3063 	test.Printf(_L("filter1 off   filter2 off             %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  3064 
  3065 	Trace.SetFilter(BTrace::ETest1,1);
  3066 	Trace.SetFilter2(0);
  3067 	UBENCH(0);
  3068 	test.Printf(_L("filter1 on    global filter2 off      %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  3069 
  3070 	Trace.SetFilter2(1);
  3071 	UBENCH(1);
  3072 	test.Printf(_L("filter1 on    global filter2 on       %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  3073 
  3074 	Trace.SetFilter2(&KBTraceFilterTestUid2,1);
  3075 	UBENCH(0);
  3076 	test.Printf(_L("filter1 on    1 UID filter2 off       %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  3077 
  3078 	Trace.SetFilter2(&KBTraceFilterTestUid1,1);
  3079 	UBENCH(1);
  3080 	test.Printf(_L("filter1 on    1 UID filter2 on        %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  3081 
  3082 	Trace.SetFilter2(BigFilter2,sizeof(BigFilter2)/sizeof(TUint32));
  3083 	Trace.SetFilter2(KBTraceFilterTestUid1,0);
  3084 	UBENCH(0);
  3085 	test.Printf(_L("filter1 on    100 UID filter2 off     %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  3086 
  3087 	Trace.SetFilter2(BigFilter2,sizeof(BigFilter2)/sizeof(TUint32));
  3088 	UBENCH(1);
  3089 	test.Printf(_L("filter1 on    100 UID filter2 on      %6d ns   %6d ns   %6d ns\n"),t1,t2,t3);
  3090 
  3091 	Trace.SetFilter(BTrace::ETest1,0);
  3092 	Trace.SetFilter2(0);
  3093 	}
  3094 
  3095 
  3096 void CallUtrace(TBool aType, TBool aContextPresent, TBool aPcPresent, TInt aSizeOfData)
  3097 	{
  3098 	if(!(aType&RBTraceTest::EUserTrace))
  3099 		{
  3100 		// use driver to create a kernel trace...
  3101 		TraceTest.Trace(aType,KTestTrace1,aSizeOfData);
  3102 		return;
  3103 		}
  3104 
  3105 	TUint32* data = (TUint32*)KTestTrace1;
  3106 	TUint16 formatId = (TUint16)data[2];
  3107 	//multiparted traces (depending on size)
  3108 	if(aSizeOfData <= 0)
  3109 		{
  3110 		UTRACE_SECONDARY(BTrace::ETest1, KBTraceFilterTestUid1, aContextPresent, aPcPresent, KUtracePcValues[1], formatId);
  3111 		UTRACE_SECONDARY(BTrace::ETest1, KBTraceFilterTestUid1, aContextPresent, aPcPresent, KUtracePcValues[2], formatId);
  3112 		}
  3113 	else if(aSizeOfData <= 4)
  3114 		{
  3115 		UTRACE_SECONDARY_4(BTrace::ETest1, KBTraceFilterTestUid1, aContextPresent, aPcPresent, KUtracePcValues[1], formatId, data[3]);
  3116 		UTRACE_SECONDARY_4(BTrace::ETest1, KBTraceFilterTestUid1, aContextPresent, aPcPresent, KUtracePcValues[2], formatId, data[3]);
  3117 		}
  3118 	else //aSizeOfData > 8
  3119 		{
  3120 		UTRACE_SECONDARY_ANY(BTrace::ETest1, KBTraceFilterTestUid1, aContextPresent, aPcPresent, KUtracePcValues[1], formatId, data+3, aSizeOfData);
  3121 		UTRACE_SECONDARY_ANY(BTrace::ETest1, KBTraceFilterTestUid1, aContextPresent, aPcPresent, KUtracePcValues[2], formatId, data+3, aSizeOfData);
  3122 		//BTraceFilteredContextPcBig(BTrace::ETest1,KTest1SubCategory,KBTraceFilterTestUid1,data+2,aSizeOfData-4);
  3123 		//BTraceFilteredContextPcBig(BTrace::ETest1,KTest1SubCategory,KBTraceFilterTestUid1,data+2,aSizeOfData-4);
  3124 		}
  3125 	}
  3126 
  3127 
  3128 void CheckUtraceFlags(TUint8* aData, TUint8* aData2, TBool aContextPresent, TBool aPcPresent)
  3129 	{
  3130 	TUint offset = ContextOffset(aData);
  3131 	if(aContextPresent)
  3132 		{
  3133 		aContextPresent = BTrace::EContextIdPresent;
  3134 		test((aContextPresent == (aData[BTrace::EFlagsIndex]&BTrace::EContextIdPresent)));
  3135 		test_Equal(ThisTraceContextId, ((TUint32*)(aData+offset))[0] );
  3136 		test_Equal(ThisTraceContextId, ((TUint32*)(aData2+offset))[0] );
  3137 		}
  3138 	if(aPcPresent)
  3139 		{
  3140 		aPcPresent = BTrace::EPcPresent;
  3141 		test((aPcPresent == (aData[BTrace::EFlagsIndex]&BTrace::EPcPresent)));
  3142 		if(aContextPresent)
  3143 			{
  3144 			test_Compare(((TUint32*)(aData+offset))[1], ==, KUtracePcValues[1]); //(offset plus 1 because context id is before pc)
  3145 			test_Compare(((TUint32*)(aData2+offset))[1], ==, KUtracePcValues[2]);
  3146 			}
  3147 		else
  3148 			{
  3149 			test_Compare(((TUint32*)(aData+offset))[0], ==, KUtracePcValues[1]);
  3150 			test_Compare(((TUint32*)(aData2+offset))[0], ==, KUtracePcValues[2]);
  3151 			}
  3152 		}
  3153 	}
  3154 
  3155 void SetupTestDataForUtrace(TBool aChangeData = ETrue)
  3156 	{
  3157 	if(aChangeData)//change to accomodate iFormatId only being 16 bit
  3158 		{
  3159 			KTestTrace1[10] = (TUint8) 0;
  3160 			KTestTrace1[11] = (TUint8) 0;
  3161 		}
  3162 	else //restore to original data
  3163 		{
  3164 		KTestTrace1[10] = (TUint8) 10;
  3165 		KTestTrace1[11] = (TUint8) 11;
  3166 		}
  3167 	}
  3168 
  3169 //---------------------------------------------
  3170 //! @SYMTestCaseID 			KBASE-T_BTRACE-2441
  3171 //! @SYMTestType 			UT
  3172 //! @SYMPREQ 				CR1623
  3173 //! @SYMTestCaseDesc 		Test UTraces, including multiparted utraces, only testing user side for now, kernel side will be added later
  3174 //! @SYMTestActions			Generate traces from kernel code using the UTrace macros as defined above,
  3175 //! @SYMTestExpectedResults Traces where broken down into multiple parts and
  3176 //!							all trace contents captured by RBTrace matched those specified
  3177 //!							at point of trace generation. Also, where appropriate, PC and/or
  3178 //!							Context ID values are present and correct.
  3179 //! @SYMTestPriority 		High
  3180 //! @SYMTestStatus 			Prototype
  3181 //---------------------------------------------
  3182 void TestUtrace(TBool aUserTrace, TBool aFilter2)
  3183 	{
  3184 	test.Next(_L("Testing utrace\n"));
  3185 	TInt oldSize = Trace.BufferSize();
  3186 	TInt r = Trace.ResizeBuffer(0x100000);
  3187 	test_KErrNone(r);
  3188 	Trace.SetMode(RBTrace::EEnable);
  3189 
  3190 	//set up the test data for UTrace
  3191 	SetupTestDataForUtrace();
  3192 
  3193 	// dummy trace do get current thread context id
  3194 	Trace.SetFilter(BTrace::ETest1,0);
  3195 	ThisTraceContextId = TraceTest.Trace(BTrace::EContextIdPresent,KTestTrace1,0);
  3196 
  3197 	// create a test filter...
  3198 	TInt extraFlags = 0;
  3199 	if(aUserTrace)
  3200 		extraFlags |= RBTraceTest::EUserTrace;
  3201 	TInt minSize = 4;
  3202 	if(aFilter2)
  3203 		{
  3204 		extraFlags |= RBTraceTest::EFilter2Trace;
  3205 		minSize += 4;
  3206 		}
  3207 
  3208 	//Test that filtering works...
  3209 	TInt filterMode;
  3210 	for(filterMode=0; filterMode<(aFilter2?6:2); ++filterMode)
  3211 		{
  3212 
  3213 		// setup filters...
  3214 		Trace.SetFilter(BTrace::ETest1,1);
  3215 		Trace.SetFilter2(BigFilter2,KNumBTraceFilterTestUids);
  3216 		if(filterMode==0 || filterMode==2)
  3217 			Trace.SetFilter(BTrace::ETest1,0); // disable in primary filter
  3218 		if(filterMode==0 || filterMode==1)
  3219 			Trace.SetFilter2(KBTraceFilterTestUid1,0); // disable in secondary filter
  3220 		if(filterMode==4)
  3221 			Trace.SetFilter2(0); // disable entire secondary filter
  3222 		if(filterMode==5)
  3223 			Trace.SetFilter2(1); // enable entire secondary filter
  3224 
  3225 		// expectTrace is true if we expect trace to be output...
  3226 		TBool expectTrace = aFilter2 ? (filterMode==3 || filterMode==5) : filterMode&1;
  3227 
  3228 		switch(filterMode)
  3229 			{
  3230 		case 0: test.Next(_L("Test with primary filter OFF, secondary filter OFF")); break;
  3231 		case 1: test.Next(_L("Test with primary filter ON, secondary filter OFF")); break;
  3232 		case 2: test.Next(_L("Test with primary filter OFF, secondary filter ON")); break;
  3233 		case 3: test.Next(_L("Test with primary filter ON, secondary filter ON")); break;
  3234 		case 4: test.Next(_L("Test with primary filter ON, global secondary filter OFF")); break;
  3235 		case 5: test.Next(_L("Test with primary filter ON, global secondary filter ON")); break;
  3236 			}
  3237 
  3238 		TBool contextPresent = EFalse;
  3239 		TBool pcPresent = EFalse;
  3240 		for(TInt flags = 0; flags < 4; flags++)
  3241 			{
  3242 			switch(flags)
  3243 				{
  3244 				case 0:	test.Printf(_L("ContextId OFF, Pc OFF\n")); break;
  3245 				case 1: contextPresent = ETrue; extraFlags = BTrace::EContextIdPresent|BTrace::EPcPresent|extraFlags; test.Printf(_L("ContextId ON, Pc OFF\n"));break;
  3246 				case 2: pcPresent = ETrue; extraFlags = BTrace::EContextIdPresent|BTrace::EPcPresent|extraFlags; test.Printf(_L("ContextId OFF, Pc ON\n"));break;
  3247 				case 3: contextPresent = ETrue; pcPresent = ETrue; extraFlags = BTrace::EContextIdPresent|BTrace::EPcPresent|extraFlags; test.Printf(_L("ContextId ON, Pc ON\n"));break;
  3248 				}
  3249 
  3250 			// multiparted traces...
  3251 			BigTraceBeginTest();
  3252 			for(TInt i=0; i<=(TInt)sizeof(KTestTrace1)-4; i++)
  3253 				{
  3254 				//CallUtrace(typeOfCall, contextPresent, pcPresent, i);
  3255 				CallUtrace(extraFlags, contextPresent, pcPresent, i);
  3256 
  3257 				TUint8* data;
  3258 				TUint8* data2;
  3259 				TInt size = Trace.GetData(data);
  3260 				if(!expectTrace)
  3261 					{
  3262 					test(!size);
  3263 					continue;
  3264 					}
  3265 				size /= 2;
  3266 				data2 = data+size;
  3267 
  3268 				TInt sizePlusFormatId = i + 8;
  3269 				test(CheckBigTrace1(data, size, sizePlusFormatId, KTest1SubCategory, 4));
  3270 				test(CheckBigTrace1(data2, size, sizePlusFormatId, KTest1SubCategory, 4));
  3271 
  3272 				CheckUtraceFlags(data, data2, contextPresent, pcPresent);
  3273 				Trace.DataUsed();
  3274 				}
  3275 			test_Equal(expectTrace,BigTraceEndTest()); // check we actually got multipart traces
  3276 			}
  3277 		}
  3278 
  3279 	//Restore trace data
  3280 	SetupTestDataForUtrace(EFalse);
  3281 
  3282 	test.Next(_L("Restore buffer\n"));
  3283 	r = Trace.ResizeBuffer(oldSize);
  3284 	test_KErrNone(r);
  3285 	Trace.SetFilter2(0);
  3286 	}
  3287 
  3288 
  3289 
  3290 GLDEF_C TInt E32Main()
  3291     {
  3292 	// initialise test trace data...
  3293 	KTestTrace1[0] = BTrace::ETest1;
  3294 	TUint i;
  3295 	for(i=8; i<sizeof(KTestTrace1); i++)
  3296 		{
  3297 		KTestTrace1[i] = (TUint8)i;
  3298 		KTestTrace2[i] = (TUint8)~i;
  3299 		}
  3300 	KTestTrace1[4] = (KBTraceFilterTestUid1>>0)&0xff;
  3301 	KTestTrace1[5] = (KBTraceFilterTestUid1>>8)&0xff;
  3302 	KTestTrace1[6] = (KBTraceFilterTestUid1>>16)&0xff;
  3303 	KTestTrace1[7] = (KBTraceFilterTestUid1>>24)&0xff;
  3304 
  3305 	KTestTrace2[4] = (KBTraceFilterTestUid2>>0)&0xff;
  3306 	KTestTrace2[5] = (KBTraceFilterTestUid2>>8)&0xff;
  3307 	KTestTrace2[6] = (KBTraceFilterTestUid2>>16)&0xff;
  3308 	KTestTrace2[7] = (KBTraceFilterTestUid2>>24)&0xff;
  3309 
  3310 	for(i=0; i<KNumBTraceFilterTestUids; i++)
  3311 		BigFilter2[i] = KBTraceFilterTestUid+i;
  3312 
  3313 	test.Title();
  3314 	TInt r;
  3315 
  3316 	test.Start(_L("Open LDD"));
  3317 	r = Trace.Open();
  3318 	test_KErrNone(r);
  3319 
  3320 	test.Next(_L("Open test LDD"));
  3321 	r = User::LoadLogicalDevice(RBTraceTest::Name());
  3322 	test(r==KErrNone || r==KErrAlreadyExists);
  3323 	r = TraceTest.Open();
  3324 	test_KErrNone(r);
  3325 
  3326 	// save trace settings...
  3327 	TUint savedMode = Trace.Mode();
  3328 	SetBTraceFilter(OldTraceFilter,OldTraceFilter);
  3329 
  3330 	TBuf<256> commandLine;
  3331 	User::CommandLine(commandLine);
  3332 	if(commandLine==_L("dump"))
  3333 		{
  3334 		test.Next(_L("Dumping trace buffer..."));
  3335 		DumpTrace();
  3336 		goto done;
  3337 		}
  3338 	else if(commandLine==_L("soak"))
  3339 		{
  3340 		test.Next(_L("Running endless soak test..."));
  3341 		for(;;)
  3342 			{
  3343 			test.Next(_L("Soak test in free-running mode"));
  3344 			TestSoak(RBTrace::EFreeRunning,60);
  3345 			test.Next(_L("Soak test in sample mode"));
  3346 			TestSoak(0,60);
  3347 			}
  3348 		}
  3349 
  3350 	test.Next(_L("Basic tests in sample mode"));
  3351 	TestBasics(0);
  3352 	test.Next(_L("Basic tests in free-running mode"));
  3353 	TestBasics(RBTrace::EFreeRunning);
  3354 	test.Next(_L("User BTrace test in sample mode"));
  3355 	TestUserTrace(0);
  3356 	test.Next(_L("Check secondary filter"));
  3357 	TestFilter2();
  3358 
  3359 	test.Next(_L("Test user traces"));
  3360 	TestTrace(ETrue,EFalse);
  3361 	test.Next(_L("Test kernel traces"));
  3362 	TestTrace(EFalse,EFalse);
  3363 	test.Next(_L("Test user traces using secondary filter"));
  3364 	TestTrace(ETrue,ETrue);
  3365 	test.Next(_L("Test kernel traces using secondary filter"));
  3366 	TestTrace(EFalse,ETrue);
  3367 
  3368 	test.Next(_L("Big user traces"));
  3369 	TestBig(ETrue,EFalse);
  3370 	test.Next(_L("Big kernel traces"));
  3371 	TestBig(EFalse,EFalse);
  3372 	test.Next(_L("Big user traces using secondary filter"));
  3373 	TestBig(ETrue,ETrue);
  3374 	test.Next(_L("Big kernel traces using secondary filter"));
  3375 	TestBig(EFalse,ETrue);
  3376 
  3377 	test.Next(_L("Test category EThreadIdentification"));
  3378 	TestThreadIdentification();
  3379 	test.Next(_L("Test category ECpuUsage"));
  3380 	TestCpuUsage();
  3381 
  3382 	test.Next(_L("Soak test in sample mode"));
  3383 	TestSoak(0,10);
  3384 	test.Next(_L("Soak test in free-running mode"));
  3385 	TestSoak(RBTrace::EFreeRunning,10);
  3386 
  3387 	test.Next(_L("Benchmark kernel tracing"));
  3388 	TestBenchmark(0);
  3389 	test.Next(_L("Benchmark user tracing"));
  3390 	TestBenchmark(1);
  3391 
  3392 	test.Next(_L("Test category EHeap"));
  3393 	TestHeapAndChunkTrace();
  3394 
  3395 	test.Next(_L("Test user side utraces"));
  3396 	TestUtrace(ETrue, ETrue);
  3397 	//Kernel side is currently not implemented
  3398 	//test.Next(_L("Test kernel side utraces"));
  3399 	//TestUtrace(EFalse, ETrue);
  3400 	test.Next(_L("Benchmark user side UTraces"));
  3401 	TestUtraceBenchmark(ETrue);
  3402 
  3403 done:
  3404 	// restore trace settin	gs...
  3405 	Trace.SetMode(0);
  3406 	SetBTraceFilter(OldTraceFilter,OldTraceFilter);
  3407 	Trace.SetMode(savedMode);
  3408 
  3409 	test.Next(_L("Close LDD"));
  3410 	Trace.Close();
  3411 	TraceTest.Close();
  3412 	User::FreeLogicalDevice(RBTraceTest::Name());
  3413 
  3414 	//test RHeap instrumentation:
  3415 	//with BTrace:EHeap:EHeapAllocFail trace points
  3416 	TestHeapAllocFailEvent(BTrace::EHeapAllocFail);
  3417 	//with BTrace:EHeap:EHeapReAllocFail trace points
  3418 	TestHeapAllocFailEvent(BTrace::EHeapReAllocFail);
  3419 	//with BTrace:EHeap:EHeapCorruption trace points
  3420 	TestHeapCorruptionEvents();
  3421 
  3422 	test.End();
  3423 	return(0);
  3424     }
  3425