diff -r 000000000000 -r c6b0df440bee dbgsrv/coredumpserver/test/automatictests/tcds_kernel/src/cds/t_coredumpserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dbgsrv/coredumpserver/test/automatictests/tcds_kernel/src/cds/t_coredumpserver.cpp Tue Mar 02 10:33:16 2010 +0530 @@ -0,0 +1,347 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +/** + @file + @internalTechnology +*/ + +#include "t_coredumpserver.h" +#include "flashdatasource.h" + +//Names of functions to be tested - referenced from script file +_LIT(KDataViaDataSource, "DataViaDataSource"); +_LIT(KTraceViaDataSource, "TraceViaDataSource"); +_LIT(KUntrustedAccess, "UntrustedDataAccess"); +/** + * Constructor for test wrapper + */ +CCoreDumpServerWrapper::CCoreDumpServerWrapper() + { + } + +/** + * Destructor + */ +CCoreDumpServerWrapper::~CCoreDumpServerWrapper() + { + iCoreDumpSession.Close(); + iSecSess.Close(); + } + +/** + * Two phase constructor for CCoreDumpServerWrapper + * @return CProcessCrashWrapper object + * @leave + */ +CCoreDumpServerWrapper* CCoreDumpServerWrapper::NewL() + { + CCoreDumpServerWrapper* ret = new (ELeave) CCoreDumpServerWrapper(); + CleanupStack::PushL(ret); + ret->ConstructL(); + CleanupStack::Pop(ret); + return ret; + } + +/** + * Safe construction + * @leave + */ +void CCoreDumpServerWrapper::ConstructL() + { + User::LeaveIfError(iCoreDumpSession.Connect()); + + TVersion secVers(Debug::KDebugServMajorVersionNumber, Debug::KDebugServMinorVersionNumber, Debug::KDebugServPatchVersionNumber); + User::LeaveIfError(iSecSess.Connect(secVers)); + } + +/** + * Assign the object + * @param aObject TAny* to the object to test + * @leave + */ +void CCoreDumpServerWrapper::SetObjectL(TAny* aObject) + {} + +/** + * Runs a test preamble + */ +void CCoreDumpServerWrapper::PrepareTestL() + { + SetBlockResult(EPass); + INFO_PRINTF1(_L("CCoreDumpMonitorWrapper::Ready to start test")); + } + +/** + * Handle a command invoked from the script + * @param aCommand Is the name of the command for a TBuf + * @param aSection Is the .ini file section where parameters to the command are located + * @param aAsyncErrorIndex Is used by the TEF Block framework to handle asynchronous commands. + */ +TBool CCoreDumpServerWrapper::DoCommandL(const TTEFFunction& aCommand, const TTEFSectionName& aSection, const TInt aAsyncErrorIndex) + { + //__UHEAP_MARK; + + PrepareTestL(); + + if (KDataViaDataSource() == aCommand) + { + TestDataSourceReturnsSystemCrashDataL(); + } + else if(KTraceViaDataSource() == aCommand) + { + TestDataSourceReturnsTraceDataL(); + } + else if(KUntrustedAccess() == aCommand) + { + TestUntrustedServerAccessL(); + } + else + { + return EFalse; + } + + //__UHEAP_MARKEND; + + return ETrue; + } + +/** + * This makes sure a formatter can retrieve data via the flash data source + */ +void CCoreDumpServerWrapper::TestDataSourceReturnsSystemCrashDataL() + { + INFO_PRINTF1(_L("TestDataSourceReturnsSystemCrashData")); + + //Load Test Formatter + CFlashDataSource* src = CFlashDataSource::NewL(iSecSess); + CleanupStack::PushL(src); + + RCrashInfoPointerList* crashList = new(ELeave)RCrashInfoPointerList; + TCleanupItem listCleanup(CCoreDumpServerWrapper::CleanupCrashList, (TAny*)crashList); + CleanupStack::PushL(listCleanup); + + //Get the crashes from the flash partition + iCoreDumpSession.ListCrashesInFlashL(*crashList); + + if(crashList->Count() == 0) + { + ERR_PRINTF1(_L("Failed to find any crashes in the flash that we could check out")); + SetBlockResult(EFail); + CleanupStack::PopAndDestroy(2); + return; + } + + INFO_PRINTF2(_L("Found [%d] crash(es) on the partition"), crashList->Count()); + + INFO_PRINTF1(_L("Analysing crash 0")); + src->AnalyseCrashL(((*crashList)[0])->iCrashId); + + INFO_PRINTF1(_L("Analysis successful")); + + //Now we try and read back the core header via the flash data source + const TCrashInfoHeader& header = src->GetCrashHeader(); + + //There isn't much checking we can do here as a lot of the things are determinable. + //Its only a smoke test anyway to make sure the data source is functioning + INFO_PRINTF1(_L("Checking the process ID that crashed was 1")); + if(header.iPid != 0x1) + { + ERR_PRINTF1(_L("Failed to retrieve proper crashed process ID")); + SetBlockResult(EFail); + CleanupStack::PopAndDestroy(2); + return; + } + + INFO_PRINTF1(_L("Checking a valid crashed process ID")); + if(header.iTid <= 0x1) + { + ERR_PRINTF1(_L("Failed to retrieve proper crashed process ID")); + SetBlockResult(EFail); + CleanupStack::PopAndDestroy(2); + return; + } + + const TRmdArmExcInfo registers = src->GetCrashContext(); + + const TUint32 cpsr = registers.iCpsr; + + INFO_PRINTF1(_L("Checking a valid CPSR and were in SVR mode when we crashed")); + if(KCPSRUsrMode == (cpsr & 0x1F)) + { + ERR_PRINTF2(_L("CPSR = 0x%X --> Not in SVR mode"), cpsr); + SetBlockResult(EFail); + CleanupStack::PopAndDestroy(2); + return; + } + + //Now, erase the partition + + TRAPD(err, iCoreDumpSession.DeleteCrashPartitionL()); + if(KErrNone != err) + { + RDebug::Printf("\ndeleteing failed with %d", err); + } + + INFO_PRINTF1(_L("Negative test. Testing flash data source does as expected when there is no data in partition")); + + TRAP(err, src->AnalyseCrashL(0)); + if(KErrNone == err) + { + ERR_PRINTF1(_L("Were able to analyse a non existant crash with KErrNone")); + SetBlockResult(EFail); + CleanupStack::PopAndDestroy(2); + return; + } + + INFO_PRINTF2(_L("Analysis gave %d as expected"), err); + + CleanupStack::PopAndDestroy(2); + } + +/** + * Testing we can retrieve trace data when it is present + */ +void CCoreDumpServerWrapper::TestDataSourceReturnsTraceDataL() + { + INFO_PRINTF1(_L("TestDataSourceReturnsTraceDataL")); + + //Load Test Formatter + CFlashDataSource* src = CFlashDataSource::NewL(iSecSess); + CleanupStack::PushL(src); + + RCrashInfoPointerList* crashList = new(ELeave)RCrashInfoPointerList; + TCleanupItem listCleanup(CCoreDumpServerWrapper::CleanupCrashList, (TAny*)crashList); + CleanupStack::PushL(listCleanup); + + //Get the crashes from the flash partition + iCoreDumpSession.ListCrashesInFlashL(*crashList); + + if(crashList->Count() == 0) + { + ERR_PRINTF1(_L("Failed to find any crashes in the flash that we could check out")); + SetBlockResult(EFail); + CleanupStack::PopAndDestroy(2); + return; + } + + INFO_PRINTF2(_L("Found [%d] crash(es) on the partition"), crashList->Count()); + + INFO_PRINTF1(_L("Analysing crash 0")); + src->AnalyseCrashL(((*crashList)[0])->iCrashId); + + INFO_PRINTF1(_L("Analysis successful")); + + TUint sizeToRead = 0x100; + RBuf8 traceData; + traceData.CreateL(sizeToRead); + traceData.CleanupClosePushL(); + + INFO_PRINTF1(_L("Reading the trace buffer")); + + TRAPD(err, src->ReadTraceBufferL(traceData)); + if(err != KErrNone) + { + ERR_PRINTF1(_L("Failed to get trace data")); + SetBlockResult(EFail); + CleanupStack::PopAndDestroy(3); + return; + } + + INFO_PRINTF1(_L("Making sure the trace data is correct")); + + //Can't analyse this data, just make sure its there + if(sizeToRead != traceData.Length()) + { + ERR_PRINTF1(_L("Didnt read all the trace data there")); + SetBlockResult(EFail); + CleanupStack::PopAndDestroy(3); + return; + } + + INFO_PRINTF1(_L("Trying to read with a zero sized buffer")); + + //See what happens when we put in a zero size buffer + RBuf8 buf; + buf.CreateL(0); + buf.CleanupClosePushL(); + + TRAP(err, src->ReadTraceBufferL(buf)); + if(err != KErrNone) + { + ERR_PRINTF1(_L("Failed to get trace data with a zero size buffer")); + SetBlockResult(EFail); + CleanupStack::PopAndDestroy(4); + return; + } + + CleanupStack::PopAndDestroy(4); + } + +/** + * This tests that untrusted clients cannot do things with the CDS that they shouldnt + */ +void CCoreDumpServerWrapper::TestUntrustedServerAccessL() + { + INFO_PRINTF1(_L("TestUntrustedServerAccessL")); + + INFO_PRINTF1(_L("Testing we can't list crashes from the flash partition")); + + RCrashInfoPointerList* crashList = new(ELeave)RCrashInfoPointerList; + TRAPD(err, iCoreDumpSession.ListCrashesInFlashL(*crashList)); + if(err != KErrPermissionDenied) + { + delete crashList; + ERR_PRINTF1(_L("Allowed to List crashes - shouldnt be. Are you sure the CDS token isn't in the ROM or on the device?")); + SetBlockResult(EFail); + return; + } + + delete crashList; + + INFO_PRINTF1(_L("Testing we can't delete the flash partition")); + TRAP(err, iCoreDumpSession.DeleteCrashPartitionL()); + if(err != KErrPermissionDenied) + { + ERR_PRINTF1(_L("Allowed to delete flash partition - shouldnt be. Are you sure the CDS token isn't in the ROM or on the device?")); + SetBlockResult(EFail); + return; + } + + INFO_PRINTF1(_L("Testing we can't process crash logs")); + TRAP(err, iCoreDumpSession.ProcessCrashLogL(0)); + if(err != KErrPermissionDenied) + { + ERR_PRINTF2(_L("Allowed to process crash logs (%d) - shouldn't be. Are you sure the CDS token isn't in the ROM or on the device?"), err); + SetBlockResult(EFail); + return; + } + + INFO_PRINTF1(_L("All is good. Move along, nothing to see here")); + } + +/** + * Cleanup item implementation for RCrashInfoPointerList + * @param aArray pointer to the list that is supposed to be freed +*/ +void CCoreDumpServerWrapper::CleanupCrashList(TAny *aArray) + { + RCrashInfoPointerList* crashList = static_cast (aArray); + crashList->ResetAndDestroy(); + crashList->Close(); + delete crashList; + } + +//eof