// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// f32test\server\t_ftrace.cpp
//
//
#include <f32file.h>
#include <f32tracedef.h>
#include <e32test.h>
#include "t_server.h"
#include "../../../kernel/eka/include/d32btrace.h"
#include "../../../kernel/eka/include/e32btrace.h"
#include <utraceefsrv.h>
RTest test(_L("T_FTRACE"));
RBTrace Trace;
void SetBTraceFilter(const TUint32* aNew,TUint32* aOld)
{
TUint category = 0;
do
{
TUint32 newBits = *aNew++;
TUint32 oldBits = 0;
do
{
oldBits >>= 1;
if(Trace.SetFilter(category,newBits&1))
oldBits |= 0x80000000u;
newBits >>= 1;
++category;
}
while(category&31);
if(aOld)
*aOld++ = oldBits;
}
while(category<256);
}
//---------------------------------------------------------------------------------------------------------------------
//! @SYMTestCaseID KBASE-T_FTRACE-0001
//! @SYMTestCaseDesc Test File Server Tracing of RFile::Replace()
//! @SYMTestType UT
//! @SYMPREQ PREQ1617
//! @SYMTestPriority Medium
//! @SYMTestActions
//! 1. Call RFile::Replace() to create a file
//! 2. Get trace data from BTrace and verify that the expected trace data is present
//!
//! @SYMTestExpectedResults
//! 1. Trace data payload should be as expected, i.e. it should contain the file name, mode etc.
//---------------------------------------------------------------------------------------------------------------------
void TestRFileReplace()
{
test.Start(_L("Test trace output from creating a file"));
RFile file;
TFileName testFileName = _L("File.txt");
TheFs.Delete(testFileName);
Trace.Empty();
TInt r = file.Replace(TheFs,testFileName,EFileStreamText);
test(r==KErrNone);
TBool funcInFound = EFalse;
TBool funcOutFound = EFalse;
TBuf8<1024> buf;
for(;;)
{
TUint8* record;
TInt dataSize = Trace.GetData(record);
if(!dataSize)
break;
TUint8* end = record+dataSize;
while(record<end)
{
TUint size = record[BTrace::ESizeIndex];
TUint flags = record[BTrace::EFlagsIndex];
TUint category = record[BTrace::ECategoryIndex];
TUint subCategory = record[BTrace::ESubCategoryIndex];
TUint8* data = record+4;
size -= 4;
buf.Zero();
if(flags&(BTrace::EHeader2Present))
{
data += 4;
size -= 4;
}
if((flags&(BTrace::ETimestampPresent|BTrace::ETimestamp2Present))==(BTrace::ETimestampPresent|BTrace::ETimestamp2Present))
{
buf.AppendFormat(_L8("time:%08x:%08x "),((TUint32*)data)[1],*(TUint32*)data);
data += 8;
size -= 8;
}
else if(flags&(BTrace::ETimestampPresent|BTrace::ETimestamp2Present))
{
buf.AppendFormat(_L8("time:%08x "),*(TUint32*)data);
data += 4;
size -= 4;
}
if(flags&(BTrace::EContextIdPresent))
{
buf.AppendFormat(_L8("context:%08x "),*(TUint32*)data);
data += 4;
size -= 4;
}
else
{
buf.AppendFormat(_L8(" "));
}
if(flags&(BTrace::EPcPresent))
{
buf.AppendFormat(_L8("pc:%08x "),*(TUint32*)data);
data += 4;
size -= 4;
}
if(flags&(BTrace::EExtraPresent))
{
data += 4;
size -= 4;
}
TUint32 data0 = (size>0) ? *(TUint32*)(data) : 0;
TUint32 data1 = (size>4) ? *(TUint32*)(data+4) : 0;
TPtrC8 des(0,0);
if(size>=8)
des.Set(data+8,size-8);
buf.AppendFormat(_L8("size:%d flags:%02x cat:%d,%d data: "),size,flags,category,subCategory);
for(TUint i=0; i<size; i+=4)
buf.AppendFormat(_L8("%08x "),*(TUint32*)(data+i));
buf.Append('\r');
buf.Append('\n');
test(buf.MaxLength() >= (buf.Length()*2));
RDebug::RawPrint(buf.Expand());
if (category == UTF::EBorder && subCategory == 0 && data0 == EF32TraceUidEfsrv)
{
if (data1 == UTraceModuleEfsrv::EFileReplace)
{
TInt sessionHandle = (size>8) ? *(TUint32*)(data+8) : 0;
TUint32 fileMode = (size>12) ? *(TUint32*)(data+12) : 0;
TInt fileNameLen = (size>16) ? *(TUint32*)(data+16) : 0;
fileNameLen/= 2; // convert to unicode length
TText16* fileName = (TText16*) ((size>20) ? (data+20) : NULL);
test(sessionHandle == TheFs.Handle());
test(fileMode == EFileStreamText);
test(fileNameLen == testFileName.Length());
TPtrC16 fileNamePtr (fileName, fileNameLen);
test(fileName != NULL);
test(testFileName.Compare(fileNamePtr) == 0);
funcInFound = ETrue;
}
else if (data1 == UTraceModuleEfsrv::EFileReplaceReturn)
{
TInt retCode = (size>8) ? *(TUint32*)(data+8) : 0;
TInt subsessionHandle = (size>12) ? *(TUint32*)(data+12) : 0;
test(retCode == KErrNone);
test(subsessionHandle == file.SubSessionHandle());
funcOutFound = ETrue;
}
}
record = BTrace::NextRecord(record);
}
Trace.DataUsed();
}
file.Close();
TheFs.Delete(testFileName);
test (funcInFound);
test (funcOutFound);
}
//---------------------------------------------------------------------------------------------------------------------
//! @SYMTestCaseID KBASE-T_FTRACE-0002
//! @SYMTestCaseDesc Test File Server Tracing of RFs::Rename()
//! @SYMTestType UT
//! @SYMPREQ PREQ1617
//! @SYMTestPriority Medium
//! @SYMTestActions
//! 1. Call RFile::Replace() to create a file
//! 2. Close the file
//! 3. Call RFs::Rename to rename the file
//! 4. Get trace data from BTrace and verify that the expected trace data is present
//!
//! @SYMTestExpectedResults
//! 1. Trace data payload should be as expected, i.e. it should contain both file names, etc.
//---------------------------------------------------------------------------------------------------------------------
void TestRFsRename()
{
test.Start(_L("Test trace output from renaming a file"));
RFile file;
TFileName testFileName1 = _L("File1.txt");
TFileName testFileName2 = _L("File2.txt");
TheFs.Delete(testFileName1);
TheFs.Delete(testFileName2);
TInt r = file.Replace(TheFs,testFileName1,EFileStreamText);
test(r==KErrNone || KErrAlreadyExists);
file.Close();
Trace.Empty();
r = TheFs.Rename(testFileName1, testFileName2);
test(r==KErrNone);
TBool funcInFound = EFalse;
TBool funcOutFound = EFalse;
TBuf8<1024> buf;
for(;;)
{
TUint8* record;
TInt dataSize = Trace.GetData(record);
if(!dataSize)
break;
TUint8* end = record+dataSize;
while(record<end)
{
TUint size = record[BTrace::ESizeIndex];
TUint flags = record[BTrace::EFlagsIndex];
TUint category = record[BTrace::ECategoryIndex];
TUint subCategory = record[BTrace::ESubCategoryIndex];
TUint8* data = record+4;
size -= 4;
buf.Zero();
if(flags&(BTrace::EHeader2Present))
{
data += 4;
size -= 4;
}
if((flags&(BTrace::ETimestampPresent|BTrace::ETimestamp2Present))==(BTrace::ETimestampPresent|BTrace::ETimestamp2Present))
{
buf.AppendFormat(_L8("time:%08x:%08x "),((TUint32*)data)[1],*(TUint32*)data);
data += 8;
size -= 8;
}
else if(flags&(BTrace::ETimestampPresent|BTrace::ETimestamp2Present))
{
buf.AppendFormat(_L8("time:%08x "),*(TUint32*)data);
data += 4;
size -= 4;
}
if(flags&(BTrace::EContextIdPresent))
{
buf.AppendFormat(_L8("context:%08x "),*(TUint32*)data);
data += 4;
size -= 4;
}
else
{
buf.AppendFormat(_L8(" "));
}
if(flags&(BTrace::EPcPresent))
{
buf.AppendFormat(_L8("pc:%08x "),*(TUint32*)data);
data += 4;
size -= 4;
}
if(flags&(BTrace::EExtraPresent))
{
data += 4;
size -= 4;
}
TUint32 data0 = (size>0) ? *(TUint32*)(data) : 0;
TUint32 data1 = (size>4) ? *(TUint32*)(data+4) : 0;
TPtrC8 des(0,0);
if(size>=8)
des.Set(data+8,size-8);
buf.AppendFormat(_L8("size:%d flags:%02x cat:%d,%d data: "),size,flags,category,subCategory);
for(TUint i=0; i<size; i+=4)
buf.AppendFormat(_L8("%08x "),*(TUint32*)(data+i));
buf.Append('\r');
buf.Append('\n');
test(buf.MaxLength() >= (buf.Length()*2));
RDebug::RawPrint(buf.Expand());
if (category == UTF::EBorder && subCategory == 0 && data0 == EF32TraceUidEfsrv)
{
TUint8* recData = data+8;
if (data1 == UTraceModuleEfsrv::EFsRename)
{
TInt sessionHandle = *(TUint32*) recData; recData+= 4;
TInt fileNameLen1 = *(TUint32*) recData; recData+= 4;
TText16* fileName1 = (TText16*) recData; recData+= ((fileNameLen1 +4) & ~3);
TInt fileNameLen2 = *(TUint32*) recData; recData+= 4;
TText16* fileName2 = (TText16*) recData; recData+= fileNameLen2;
fileNameLen1/= 2; // convert to unicode length
fileNameLen2/= 2; // convert to unicode length
test(sessionHandle == TheFs.Handle());
test(fileNameLen1 == testFileName1.Length());
TPtrC16 fileNamePtr1 (fileName1, fileNameLen1);
test(fileName1 != NULL);
test(testFileName1.Compare(fileNamePtr1) == 0);
test(fileNameLen2 == testFileName2.Length());
TPtrC16 fileNamePtr2 (fileName2, fileNameLen2);
test(fileName2 != NULL);
test(testFileName2.Compare(fileNamePtr2) == 0);
funcInFound = ETrue;
}
else if (data1 == UTraceModuleEfsrv::EFsRenameReturn)
{
TInt retCode = (size>8) ? *(TUint32*)(data+8) : 0;
test(retCode == KErrNone);
funcOutFound = ETrue;
}
}
record = BTrace::NextRecord(record);
}
Trace.DataUsed();
}
test (funcInFound);
test (funcOutFound);
TheFs.Delete(testFileName1);
TheFs.Delete(testFileName2);
}
void CallTestsL()
{
// By default, file server trace-points are only compiled in in debug mode
#if defined(_DEBUG)
test.Title();
TInt r;
test.Start(_L("Open LDD"));
r = Trace.Open();
test(r == KErrNone);
TUint32 OldTraceFilter[8] = {0};
TUint savedMode = Trace.Mode();
SetBTraceFilter(OldTraceFilter,OldTraceFilter);
Trace.ResizeBuffer(0x100000);
Trace.Empty();
Trace.SetMode(RBTrace::EEnable | RBTrace::EFreeRunning);
TBool b;
// b = Trace.SetFilter(BTrace::EThreadIdentification, ETrue);
// test(b >= 0);
b = Trace.SetFilter(UTF::EPanic, ETrue);
test(b >= 0);
b = Trace.SetFilter(UTF::EError, ETrue);
test(b >= 0);
b = Trace.SetFilter(UTF::EBorder, ETrue);
test(b >= 0);
b = Trace.SetFilter2(EF32TraceUidEfsrv, ETrue);
test(b >= 0);
TestRFileReplace();
TestRFsRename();
// restore trace settings...
Trace.SetMode(0);
SetBTraceFilter(OldTraceFilter,OldTraceFilter);
Trace.SetMode(savedMode);
test.Next(_L("Close LDD"));
Trace.Close();
test.End();
#endif
}