diff -r 000000000000 -r bde4ae8d615e os/persistentdata/loggingservices/eventlogger/test/src/t_logbadclient.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os/persistentdata/loggingservices/eventlogger/test/src/t_logbadclient.cpp	Fri Jun 15 03:10:57 2012 +0200
@@ -0,0 +1,468 @@
+// Copyright (c) 2006-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:
+//
+
+#include <e32test.h>
+#include <bautils.h>
+#include <e32math.h>
+#include "LogServShared.h"
+#include "logservcli.h"
+#include "t_logutil.h"
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+RTest TheTest(_L("t_logbadclient test"));
+
+const TInt KTestIterCount = 5000;
+const TInt KMaxDesArgLen = 1000;
+enum TArgType 
+	{
+	EIntArgType, 
+	ETextArgType, 
+	EBinArgType, 
+	ELastArgType
+	};
+
+const TLogServFunction KLogIpcMsgCodes[] = 
+	{
+	ELogOperationCancel, ELogOperationGetResult, ELogOperationInitiate, ELogNotify, ELogNotifyCancel, ELogViewCreate,
+	ELogViewDelete, ELogViewCount, ELogViewOperationInitiate, ELogViewChangeNotificationsRequest,
+	ELogViewChangeNotificationsCancel, ELogViewFetchChanges, ELogViewNotifyLockStatusChange, 
+	ELogViewNotifyLockStatusChangeCancel, ELogNotifyExtended, ELogNotifyExtendedCancel, ELogNOTUSED   
+	};
+
+const TLogOperationType KLogOpTypes[] =
+	{
+	ELogOperationEventAdd, ELogOperationEventGet, ELogOperationEventChange, ELogOperationEventDelete,
+	ELogOperationTypeAdd, ELogOperationTypeGet, ELogOperationTypeChange, ELogOperationTypeDelete,
+	ELogOperationClearLog,  ELogOperationClearRecent, ELogOperationConfigGet,  ELogOperationConfigChange,
+	ELogOperationMaintain, ELogOperationViewSetup, ELogOperationViewRemoveEvent, ELogOperationViewClearDuplicates,
+	ELogOperationViewSetFlags, ELogOperationViewWindowFetch, (TLogOperationType)-100
+	};
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+//If the LogEng server crashes and the test receives KErrServerTerminated error, then the 
+//next set will contain the last:
+// - iteration number;
+// - function code;
+// - IPC arguments values;
+struct TThreadData
+	{
+	TInt				iIteration;
+	TInt 				iFunction;
+	TArgType 			iArgType[KMaxMessageArguments];
+	TInt 				iIntArg[KMaxMessageArguments];
+	TBuf<KMaxDesArgLen> iTextArg[KMaxMessageArguments];
+	TBuf8<KMaxDesArgLen> iBinArg[KMaxMessageArguments];
+	TInt64 				iSeed;
+	};
+//////////////////////////////////////////////////////////////////////////////////////
+
+_LIT(KPanicCategory, "SrvTerm");
+_LIT(KPanicCategory2, "InvArg");
+const TInt KPanicCode = 1111;
+const TInt KPanicCode2 = 2222;
+
+static TLogClientServerData TheLogIpcData;
+static TPtrC8 TheLogIpcDataPtr((const TUint8*)&TheLogIpcData, sizeof(TheLogIpcData));
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+void PrintIterationCount(TInt aIteration)
+	{
+	if((aIteration % 100) == 0)
+		{
+		TTime time;
+		time.HomeTime();
+		TDateTime dt = time.DateTime();
+		TBuf<16> tbuf;
+		tbuf.Format(_L("%02d:%02d:%02d.%06d"), dt.Hour(), dt.Minute(), dt.Second(), dt.MicroSecond());
+		TheTest.Printf(_L("-----[%S] Test iterations: %d\r\n"), &tbuf, aIteration);
+		}
+	}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+//Worker thread function.
+//It behaves as a malicious client. Connects to the LogEng server. In each test iteration generates some random values
+//for the function number, handle, handle type, IPC arguments. Then sends a command to the server using these
+//randomly generated values. If the server crashes and the thread function receives KErrServerTerminated error,
+//then the thread kills itself and the main thread will get KPanicCategory and KPanicCode as a reason for the
+//worker thread's death. The last set of randomly generated values will be stored in the memory, pointed by aData argument.
+TInt ThreadFunc1(void* aData)
+	{
+	__UHEAP_MARK;
+	
+	CTrapCleanup* tc = CTrapCleanup::New();
+	TTEST(tc != NULL);
+
+	TThreadData* p = static_cast <TThreadData*> (aData);
+	TTEST(p != NULL);
+	TThreadData& data = *p;
+	
+	RLogSession sess;
+	TInt err = sess.Connect();
+	TTEST2(err, KErrNone);
+
+	while(++data.iIteration <= KTestIterCount)
+		{
+		TIpcArgs args;
+		const TInt KFnCnt = sizeof(KLogIpcMsgCodes) / sizeof(KLogIpcMsgCodes[0]);
+		TInt fnIdx = Math::Rand(data.iSeed) % KFnCnt;
+		data.iFunction = KLogIpcMsgCodes[fnIdx];
+		PrintIterationCount(data.iIteration);
+		for(TInt argIdx=0;argIdx<KMaxMessageArguments;++argIdx)
+			{
+			//Initialize arguments
+			data.iArgType[argIdx] = EBinArgType;
+			if(argIdx > 0)
+				{
+				data.iArgType[argIdx] = static_cast <TArgType> (Math::Rand(data.iSeed) % ELastArgType);
+				}
+			switch(data.iArgType[argIdx])
+				{
+				case EIntArgType:
+					data.iIntArg[argIdx] = Math::Rand(data.iSeed) % 9711;
+					args.Set(argIdx, data.iIntArg[argIdx]);
+					break;
+				case ETextArgType:
+					{
+					TInt len = Math::Rand(data.iSeed) % KMaxDesArgLen;	
+					data.iTextArg[argIdx].SetLength(len);
+					args.Set(argIdx, &data.iTextArg[argIdx]);
+					}
+					break;
+				case EBinArgType:
+					{
+					if(argIdx == 0)
+						{
+						//The operations ids are guaranteed to be sequential by logeng.dll implementation.
+						TheLogIpcData.iOperationId = data.iIteration;
+						//if(Math::Rand(data.iSeed) & 1)
+						//	{
+						//	TheLogIpcData.iOperationId = 0;
+						//	}
+						const TInt KTypeCnt = sizeof(KLogOpTypes) / sizeof(KLogOpTypes[0]);
+						TInt typeIdx = Math::Rand(data.iSeed) % KTypeCnt;
+						TheLogIpcData.iOperationType = KLogOpTypes[typeIdx];
+						TheLogIpcData.iDataSlot1 = Math::Rand(data.iSeed);
+						TheLogIpcData.iDataSlot2 = Math::Rand(data.iSeed);
+						args.Set(argIdx, &TheLogIpcDataPtr);
+						}
+					else
+						{
+						TInt len = Math::Rand(data.iSeed) % KMaxDesArgLen;	
+						data.iBinArg[argIdx].SetLength(len);
+						args.Set(argIdx, &data.iBinArg[argIdx]);
+						}
+					}
+					break;
+				default:
+					User::Panic(KPanicCategory2, KPanicCode2);
+					break;
+				}
+			}
+		//Send arguments
+		//RDebug::Print(_L("##data.iFunction=%d\r\n"), data.iFunction);
+		TRequestStatus stat;
+		sess.Send(data.iFunction, args, stat);
+		if(stat.Int() == KErrServerTerminated)
+			{
+			User::Panic(KPanicCategory, KPanicCode);
+			}
+		else if(stat.Int() == KRequestPending)
+			{
+			if(data.iFunction == ELogOperationInitiate)
+				{
+				//RDebug::Print(_L("##ELogOperationGetResult\r\n"));
+				err = sess.Send(ELogOperationGetResult, args);
+				if(err == KErrServerTerminated)
+					{
+					User::Panic(KPanicCategory, KPanicCode);
+					}
+				}
+			else
+				{
+				//Give some time to the LogEng server to do something with that async request, then cancel it.
+				//Otherwise, on a multi-core hardware, the LogEnd server will end up with a long queue of
+				//pending requests, not cleared if the client side thread is panic'd. It will be a complete chaos.
+				//RDebug::Print(_L("##data.iFunction=%d, wait and cancel async request\r\n"), data.iFunction);
+				User::After(100000);
+				TRequestStatus* s = &stat;
+				User::RequestComplete(s, KErrCancel);
+				}
+			//RDebug::Print(_L("##---err=%d\r\n"), err);
+			}
+		}
+
+	sess.Close();
+
+	delete tc;	
+	
+	__UHEAP_MARKEND;
+	
+	return KErrNone;		
+	}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+//Thread function to detect a crash in the server.
+//The server should run for the duration of the test.
+// return KErrAbort: If failure to start server
+// return KErrServerTerminated: If server process is terminated 
+
+TInt ServerWatcherFunc(TAny* /*aData*/)
+	{
+	__UHEAP_MARK;
+
+	_LIT(KLogEngServerName,"LogServ*");
+
+	TInt err;
+
+	// Start the server if not already running
+	RLogSession sess;
+	err = sess.Connect();
+	if (err != KErrNone)
+		return KErrAbort;
+	sess.Close();
+
+	TFindProcess findProcess(KLogEngServerName);
+	TFullName result;
+	if ( findProcess.Next(result) != KErrNone )
+		return KErrAbort;
+	
+	RProcess server;
+	if( server.Open(findProcess, EOwnerProcess) != KErrNone)
+		return KErrAbort;
+
+	TRequestStatus status;
+	server.Logon(status);	
+ 	User::WaitForRequest(status);
+	
+	server.Close();
+	
+	__UHEAP_MARKEND;
+
+	return KErrServerTerminated;
+	}
+
+
+/**
+@SYMTestCaseID			PDS-LOGENG-UT-4045
+@SYMTestCaseDesc		In a loop, where the loop iterations are less than KTestIterCount (5000 at the moment), 
+						the test creates a worker thread, which will behave as a malicious client. 
+						If the worker thread crashes the LogEng server, then the worker thread
+						dies notifying the main thread about the LogEng server crash. The main thread prints the 
+						values used in the last IPC call and crashes the test.
+@SYMTestPriority		High
+@SYMTestActions			LogEng, Malicious client simulation test.
+@SYMTestExpectedResults Test must not fail
+@SYMREQ					REQ12746
+*/	
+void BadClientTest()
+	{
+	// Start a thread to watch the server process
+	RThread serverWatcher;
+	TInt err = serverWatcher.Create(_L("ServerWatcher"), &ServerWatcherFunc, 0x2000, 0x1000, 0x10000, NULL, EOwnerProcess);
+	TRequestStatus serverStatus;
+	serverWatcher.Logon(serverStatus);
+	serverWatcher.Resume();
+
+	TThreadData* p = new TThreadData;
+	TEST(p != NULL);
+	TThreadData& data = *p;
+	data.iFunction = 0;
+	TTime now;
+	now.UniversalTime();
+	data.iSeed = now.Int64();
+
+	for(data.iIteration=0;data.iIteration<KTestIterCount;++data.iIteration)
+		{
+		PrintIterationCount(data.iIteration);
+		
+		//Run the malicious client (one test thread which will try to crash the LogEng server)
+		User::After(200000);
+		_LIT(KTestThreadName, "TLBCThr");
+		RThread thread;
+		err = thread.Create(KTestThreadName, &ThreadFunc1, 0x2000, 0x1000, 0x10000, &data, EOwnerProcess);
+		if(err == KErrAlreadyExists)
+			{
+			TheTest.Printf(_L("##Iteration %d. Function %d. Thread \"%S\" already exists!\r\n"), data.iIteration, data.iFunction, &KTestThreadName);
+			for(TInt i=0;i<KMaxMessageArguments;++i)
+				{
+				TheTest.Printf(_L("##Arg %d, Type %d\r\n"), i + 1, data.iArgType[i]);
+				switch(data.iArgType[i])
+					{
+					case EIntArgType:
+					    TheTest.Printf(_L("Integer, value=%d\r\n"), data.iIntArg[i]);
+						break;
+					case ETextArgType:
+					    TheTest.Printf(_L("Text, length=%d\r\n"), data.iTextArg[i].Length());
+						break;
+					case EBinArgType:
+					    TheTest.Printf(_L("Binary, length=%d\r\n"), data.iBinArg[i].Length());
+						break;
+					default:
+					    TheTest.Printf(_L("Invalid argument type: %d\r\n"), data.iArgType[i]);
+						break;
+					}
+				}
+			break;
+			}
+		TEST2(err, KErrNone);
+		User::SetJustInTime(EFalse);		
+		TRequestStatus status;
+		thread.Logon(status);
+		TEST2(status.Int(), KRequestPending);
+		thread.Resume();
+		User::WaitForRequest(status, serverStatus);
+
+		// If the Server has crashed then we must fail		
+		if (serverStatus != KRequestPending) 
+			{
+			TheTest.Printf(_L("##Iteration=%d, Function=%d, Status=%d, Server Status=%d\r\n"), data.iIteration, data.iFunction, status.Int(), serverStatus.Int());
+			}
+
+		TExitType exitType = thread.ExitType();
+		TInt exitReason = thread.ExitReason();
+		thread.Close();
+		User::SetJustInTime(ETrue);
+		
+		if(exitType == EExitPanic || serverStatus != KRequestPending)
+			{
+			if(exitReason == KPanicCode || serverStatus != KRequestPending)
+				{
+				TheTest.Printf(_L("##Server terminated!\r\n"));
+				TheTest.Printf(_L("##Iteration=%d, Function=%d, iOperationType=%d, iDataSlot1=%d, iDataSlot2=%d\r\n"), 
+						data.iIteration, data.iFunction,
+						TheLogIpcData.iOperationType,
+						TheLogIpcData.iDataSlot1,
+						TheLogIpcData.iDataSlot2);
+				for(TInt i=0;i<KMaxMessageArguments;++i)
+					{
+					TheTest.Printf(_L("##Arg %d, Type %d\r\n"), i + 1, data.iArgType[i]);
+					switch(data.iArgType[i])
+						{
+						case EIntArgType:
+						    TheTest.Printf(_L("Integer, value=%d\r\n"), data.iIntArg[i]);
+							break;
+						case ETextArgType:
+						    TheTest.Printf(_L("Text, length=%d\r\n"), data.iTextArg[i].Length());
+							break;
+						case EBinArgType:
+						    TheTest.Printf(_L("Binary, length=%d\r\n"), data.iBinArg[i].Length());
+							break;
+						default:
+						    TheTest.Printf(_L("Invalid argument type: %d\r\n"), data.iArgType[i]);
+							break;
+						}
+					}
+				TEST(0);
+				}
+			}
+		}//for
+	delete p;
+
+	// Check to see if the server crashed and not detected by client
+	TEST(serverStatus.Int() == KRequestPending);
+	serverWatcher.Kill(KErrCancel);
+	serverWatcher.Close();
+		
+	}
+
+/**
+@SYMTestCaseID			PDS-LOGENG-UT-4044
+@SYMTestCaseDesc		LogEng server startup - file I/O error simulation test.
+						The test case shuts down the LogEng server in debug mode.
+						Then attempts to connect to the server in a file I/O error simulation
+						loop.
+@SYMTestPriority		High
+@SYMTestActions			LogEng server startup - file I/O error simulation test.
+@SYMTestExpectedResults Test must not fail
+@SYMREQ					REQ12746
+*/	
+void LogEngSrvStartupFileIoErrTest()
+	{
+	//Shut down the server if it is running
+	RLogSession sess;
+	TInt err = sess.Connect();
+	TEST2(err, KErrNone);
+
+	err = sess.Send(ELogMakeTransient, TIpcArgs(1));
+	TEST2(err, KErrNone);
+	sess.Close();
+	
+	//The shutdown delay is 2 seconds (defined in LogServShutdownTimer.h file). In this csase 5 seconds is more than enough.
+	User::After(5000000);
+	
+	RFs fs;
+	err = fs.Connect();
+	TEST2(err, KErrNone);
+
+	TBool finished = EFalse;
+	TInt failCount = 0;
+
+	while(!finished)
+		{
+		fs.SetErrorCondition(KErrCorrupt, ++failCount);
+		TInt err = sess.Connect();
+		fs.SetErrorCondition(KErrNone, 0);
+		sess.Close();
+		if(err == KErrNone)
+			{
+			finished = ETrue;
+			}
+		else
+			{
+			TEST2(err, KErrCorrupt);
+			}
+		}
+
+	fs.Close();
+	TheTest.Printf(_L("===LogEng Server Startup File I/O error simularion test succeeded at iteration %d\n"), failCount);
+	}
+
+void DoTests()
+	{
+	TheTest.Start(_L(" @SYMTestCaseID:PDS-LOGENG-UT-4045: Bad client test"));
+	BadClientTest();
+#ifdef _DEBUG	
+	TheTest.Next(_L(" @SYMTestCaseID:PDS-LOGENG-UT-4044: LogEng Server Startup - File I/O error simulation test"));
+	LogEngSrvStartupFileIoErrTest();
+#endif	
+	}
+
+TInt E32Main()
+	{
+	TheTest.Title();
+	
+	CTrapCleanup* tc = CTrapCleanup::New();
+	
+	__UHEAP_MARK;
+	
+	DoTests();
+
+	__UHEAP_MARKEND;
+	
+	TheTest.End();
+	TheTest.Close();
+	
+	delete tc;
+
+	User::Heap().Check();
+	return KErrNone;
+	}