genericopenlibs/openenvcore/backend/test/testlibcbackend/src/tlibcbackendblocks.cpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genericopenlibs/openenvcore/backend/test/testlibcbackend/src/tlibcbackendblocks.cpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,669 @@
+// 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:
+// Name        : tlibcbackendblocks.cpp
+//
+
+
+
+ /*
+* ==============================================================================
+*  Name        : tlibcbackendblocks.cpp
+*  Part of     : backend / testlibcbackend
+*
+*  Description : ?Description
+*  Version:   0.5
+*
+*  Copyright (C) 2002 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+// INCLUDE FILES
+#include <e32svr.h>
+#include "tlibcbackend.h"
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <stdapis/netinet/in.h>
+#include <stdapis/arpa/inet.h>
+#include <netdb.h>
+
+#include <stdio.h>
+#include <semaphore.h>
+
+
+#define	IN_SET_LOOPBACK_ADDR(a) \
+	{ (a)->sin_addr.s_addr  = 0x0100007F; (a)->sin_family = AF_INET; }
+
+
+const char* const KThreadOneLogFile = "C:\\ThreadOneLog.txt"; 
+const char* const KThreadTwoLogFile = "C:\\ThreadTwoLog.txt"; 
+
+const TInt KPortNum 					= 2222;
+const TInt KCount 					 	= 10;
+const char KFileName[50] 				= "C:\\File.txt";
+
+#ifdef __ARMCC__
+const char* const KReadProcess = "C:\\Sys\\Bin\\TPopenReadChild.exe";
+const char* const KWriteProcess = "C:\\Sys\\Bin\\TPopenWriteChild.exe";
+#endif //__ARMCC__
+
+const short MODE_READ 			 = 1;
+const short MODE_WRITE			 = 2;
+const short MODE_READWRITE		 = 4;
+
+void* SocketReadThreadEntryPoint( void* aParam );
+void* SocketWriteThreadEntryPoint( void* aParam );
+void* FileReadThreadEntryPoint( void* aParam );
+void* FileWriteThreadEntryPoint( void* aParam );
+void* ServerLockThreadEntryPoint( void* aParam );
+
+struct TThreadParam
+	{
+	TInt iDataCount;
+	sem_t iSemaphore;
+	FILE* iFp;
+	};
+
+
+//Utility functions
+void CTestLibcbackend::ReadIntParam(TInt &aInt)
+{
+	_LIT( Kparam, "Param%d" );
+     TBuf<8> pNameBuf;
+     TPtrC string;
+     pNameBuf.Format(Kparam,++iParamCnt);
+	 TBool res = GetIntFromConfig(ConfigSection(), pNameBuf, aInt);
+	 if(!res)
+	 	{
+	 	_LIT(Kerr , "Unable to retrieve integer parameter") ;
+	 	INFO_PRINTF1(Kerr);
+	  	}
+	 return;
+}
+
+// ============================ MEMBER FUNCTIONS ===============================
+// -----------------------------------------------------------------------------
+// CTestLibcbackend::SocketIOTest
+// Testing new backend with a scenario like this:
+// create two thread which sends/receive data to each other
+// This test case can be invoked with below syntax:
+// SocketIO <NoOfMsgs:Integer> 
+// Example: SocketIO 100
+// -----------------------------------------------------------------------------
+//
+TInt CTestLibcbackend::SocketIOTest()
+    {
+    TInt dataCount = KCount;
+    ReadIntParam( dataCount );
+	int retVal = 0;
+	pthread_t threadID1 = 0;
+	pthread_t threadID2 = 0;
+	pthread_attr_t threadAttr;
+	pthread_attr_init( &threadAttr );
+	pthread_attr_setdetachstate( &threadAttr, PTHREAD_CREATE_JOINABLE );
+	
+	//Create a Read thread now
+	retVal = pthread_create( &threadID1, &threadAttr, SocketReadThreadEntryPoint, 
+		(void*)dataCount );
+	INFO_PRINTF2(_L("ReadThread Creation returned with %d"), retVal);
+	if( retVal == 0)
+		{
+		//Create Write thread
+		retVal = pthread_create( &threadID2, &threadAttr, 
+		SocketWriteThreadEntryPoint, (void*)dataCount );
+		INFO_PRINTF2(_L("WriteThread Creation returned with %d"), retVal);
+		//If its joinable thread and waitFlag id set
+		if( KErrNone == retVal )
+			{
+			TInt exitReason = 0;
+			retVal = pthread_join(threadID1, (void**)&exitReason );
+			INFO_PRINTF3(_L("ReadThread join returned with %d and the exit reason is %d"), retVal, exitReason );
+			retVal = pthread_join(threadID2, (void**)&exitReason );
+			if (retVal != 0)
+				{
+				//If the thread fails , kill the first thread 
+				pthread_join(threadID1, NULL);
+				return KErrGeneral;
+				}
+			else
+				{
+				INFO_PRINTF3(_L("WriteThread join returned with %d and the exit reason is %d"), retVal, exitReason );
+				}
+			}
+		}
+	return retVal;
+    }
+
+// -----------------------------------------------------------------------------
+// CTestLibcbackend::FileIOTest
+// Testing new backend with a scenario like this:
+// create two thread which read/write data to same file
+// This test case can be invoked with below syntax:
+// FileIO <NoOfFileIO:Integer> 
+// Example: FileIO 100
+// -----------------------------------------------------------------------------
+//
+TInt CTestLibcbackend::FileIOTest()
+    {
+	int retVal = 0;
+    TInt dataCount = KCount;
+    ReadIntParam( dataCount );
+	TThreadParam threadParam;
+	threadParam.iDataCount = dataCount;
+
+	if( sem_init( &threadParam.iSemaphore, 0, 0 ) != KErrNone )
+		{
+		INFO_PRINTF2(_L("Semaphore creation Failed with %d"), errno );
+		return KErrGeneral;
+		}
+	
+	FILE* fp = fopen( KFileName, "w+");
+	if (fp == NULL)
+		{
+		INFO_PRINTF1(_L("File open error!"));
+		return KErrGeneral;
+		}
+	threadParam.iFp = fp;
+	if(!fp)
+		{
+		return KErrGeneral;
+		}
+	
+	pthread_t threadID1 = 0;
+	pthread_t threadID2 = 0;
+	pthread_attr_t threadAttr;
+	pthread_attr_init( &threadAttr );
+	pthread_attr_setdetachstate( &threadAttr, PTHREAD_CREATE_JOINABLE );
+	
+	//Create a Read thread now
+	retVal = pthread_create( &threadID1, &threadAttr, FileReadThreadEntryPoint, 
+		(void*)&threadParam );
+	INFO_PRINTF2(_L("ReadThread Creation returned with %d"), retVal);
+	if( retVal == 0)
+		{
+		//Create Write thread
+		retVal = pthread_create( &threadID2, &threadAttr, 
+			FileWriteThreadEntryPoint, (void*)&threadParam );
+		INFO_PRINTF2(_L("WriteThread Creation returned with %d"), retVal);
+		//If its joinable thread and waitFlag id set
+		if( KErrNone == retVal )
+			{
+			TInt exitReason = 0;
+			retVal = pthread_join(threadID1, (void**)&exitReason );
+			INFO_PRINTF3(_L("ReadThread join returned with %d and the exit reason is %d"), retVal, exitReason );
+			retVal = pthread_join(threadID2, (void**)&exitReason );
+			if (retVal != 0)
+				{
+				//If the thread fails , kill the first thread 
+				pthread_join(threadID1, NULL);
+				return KErrGeneral;
+				}
+			else
+				{
+				INFO_PRINTF3(_L("WriteThread join returned with %d and the exit reason is %d"), retVal, exitReason );
+				}
+			}
+		}
+
+	if( sem_destroy( &threadParam.iSemaphore ) != KErrNone )
+		{
+		INFO_PRINTF2(_L("sem_destroy Failed with %d"), errno );
+		retVal = KErrGeneral;
+		}
+		
+	fclose(fp);
+	return retVal;
+    }
+
+// -----------------------------------------------------------------------------
+// CTestLibcbackend::ServerLockTest
+// Testing new backend's Server Session locks with multiple threads
+// This test case can be invoked with below syntax:
+// ServerLock <NoOfThreads:Integer> 
+// Example: ServerLock 10
+// -----------------------------------------------------------------------------
+//
+TInt CTestLibcbackend::ServerLockTest()
+	{
+	TInt retVal = KErrNone;
+    TInt threadCount = KCount;
+    ReadIntParam( threadCount );
+	pthread_t threadID = 0;
+	pthread_attr_t threadAttr;
+	pthread_attr_init( &threadAttr );
+	pthread_attr_setdetachstate( &threadAttr, PTHREAD_CREATE_JOINABLE );
+	
+	for(int index = 0; index<threadCount && KErrNone == retVal; index++)
+		{
+		//Create a Read thread now
+		retVal = pthread_create( &threadID, &threadAttr, ServerLockThreadEntryPoint, 
+			(void*)threadCount );
+		INFO_PRINTF2(_L("ServerLockThreadEntryPoint Creation returned with %d"), retVal);
+		}
+	TInt exitReason = 0;
+	retVal = pthread_join(threadID, (void**)&exitReason );
+	INFO_PRINTF3(_L("ServerLockThreadEntryPoint join returned with %d and the exit reason is %d"), retVal, exitReason );
+	return retVal;
+	}
+
+// -----------------------------------------------------------------------------
+// CTestLibcbackend::ServerLockTest
+// Testing backend implementation of opening a directory
+// This test case can be invoked with below syntax:
+// OpenDir <Directory to be opened: String> <Mode:Integer> 
+// Example: OpenDir c:\Logs\NotExisting MODE_WRITE
+// -----------------------------------------------------------------------------
+//
+TInt CTestLibcbackend::OpenDirTest()
+	{
+	TInt retVal = KErrNone;
+	TInt mode = MODE_READ;
+	
+	//Read Directory Name and mode from CFG file
+	TPtrC dirName;
+	_LIT( KaKey, "Param%d" );
+     TBuf<8> pNameBuf;
+     pNameBuf.Format(KaKey,++iParamCnt);
+	 TBool res = GetStringFromConfig(ConfigSection(), pNameBuf, dirName);
+	 if(!res)
+	 	{
+	 	_LIT(Kerr , "Unable to retrieve string parameter") ;
+	 	INFO_PRINTF1(Kerr);
+	  	}
+	ReadIntParam( mode );
+	switch( mode )
+		{
+		case MODE_WRITE:
+			{
+			mode = O_WRONLY;
+			break;
+			}
+		case MODE_READWRITE:
+			{
+			mode = O_RDWR;
+			break;
+			}
+		default:
+		case MODE_READ:
+			{
+			mode = O_RDONLY;
+			}
+		}
+
+	TBuf8<KMaxFileName> tempDir;
+	TChar endChar('\0');
+	tempDir.Copy(dirName);
+	tempDir.Append(endChar);
+	char* dir = (char*)tempDir.Ptr();
+	
+	char* file = "c:\\dircontents.txt";
+	int fd = open(dir, mode);
+	if( fd > 0 )
+		{
+		char buff[200];
+		int retVal = read(fd, buff, 200);
+		if( retVal > 0 )
+			{
+			FILE* fp  = fopen(file, "w");
+			if( fp )
+				{
+				for(int i=0; i<retVal; i++)
+				fprintf(fp, "%c", buff[i]);
+				fclose(fp);
+				}
+			retVal = 0;
+			}
+		close(fd);
+		}
+	//It should fail with EISDIR
+	else 
+		{
+		if( errno != EISDIR )
+			{
+			retVal = fd;
+			}
+		}
+		
+	return retVal;
+	}
+
+// -----------------------------------------------------------------------------
+// CTestLibcbackend::ServerLockTest
+// Testing backend implementation of popen API
+// This test case can be invoked with below syntax:
+// PopenPipe <Mode:Integer> 
+// Example: PopenPipe MODE_WRITE
+// -----------------------------------------------------------------------------
+//
+TInt CTestLibcbackend::PopenPipeTest()
+	{
+	TInt retVal = KErrNone;
+	TInt mode = MODE_READ;
+	char pipeMode = 'r';
+	const char* command = NULL;
+	ReadIntParam( mode );
+	
+//popen works only on device because of Symbian Emulator limitation
+#ifdef __ARMCC__
+	if ( mode == MODE_WRITE )
+		{
+		pipeMode = 'w';
+		command = KWriteProcess;
+		}
+	else
+		{
+		pipeMode = 'r';
+		command = KReadProcess;
+		}
+
+	FILE* fp = popen( command, &pipeMode);
+	if( fp )
+		{
+		if( mode == MODE_WRITE )
+			{
+			//Child Pipe Should get this string!!
+			fprintf(fp, "PROCESS");
+			}
+		else
+			{
+			//Child Pipe Should give this string!!
+			char string[50];
+			int ret = fscanf(fp, "%s", string);
+			}
+		//close the pipe
+		pclose(fp);
+		}
+	//Error case
+	else
+		{
+		int err = errno;
+		retVal = KErrGeneral;
+		}
+#endif // __ARMCC__
+
+	return retVal;
+	}
+
+// -----------------------------------------------------------------------------
+// SocketReadThreadEntryPoint
+// Thread Entry Function for Socket read thread
+// -----------------------------------------------------------------------------
+//
+void* SocketReadThreadEntryPoint( void* aParam )
+	{
+	FILE* logFile;
+	TInt retVal = KErrNone;
+	TInt count = (TInt) aParam;
+	TInt portNum = KPortNum + count;
+	int serverFd = 0;
+	int newFd = 0;
+	size_t addrSize;
+	struct sockaddr_in servAddr;
+	struct sockaddr_in sockAddr;
+	const char* buff = "Server --> Sending Data Item : ";
+	char sendBuff[50];
+	char recvBuff[100];
+	const unsigned int maxRecv = 100;
+
+	logFile = fopen(KThreadOneLogFile, "w");
+	
+	if(logFile == NULL)
+		{
+		return (void*) KErrGeneral;
+		}
+
+	fprintf(logFile, "Server Socket Thread\n");
+	serverFd = socket(AF_INET, SOCK_STREAM, 0);
+	if( serverFd == -1 )
+		{
+		fprintf(logFile, "Socket Creation Failed!!\n");
+		retVal = KErrGeneral;
+		}
+
+	IN_SET_LOOPBACK_ADDR( &servAddr );
+	servAddr.sin_port = htons( (TUint16) portNum );
+	retVal |= bind( serverFd, (struct sockaddr*)&servAddr, sizeof(servAddr) );
+	if( retVal != 0 )
+		{
+		fprintf(logFile, "Socket bind Failed!!\n");
+		close( serverFd );
+		retVal = KErrGeneral;
+		}
+
+	retVal |= listen( serverFd, 1 );
+	if( retVal != 0 )
+		{
+		fprintf(logFile, "Socket listen Failed!!\n");
+		close( serverFd );
+		retVal = KErrGeneral;
+		}
+
+	addrSize = sizeof( sockAddr );
+	newFd = accept( serverFd, (struct sockaddr*)&sockAddr, &addrSize);
+	if( newFd == -1 )
+		{
+		fprintf(logFile, "Socket accept Failed!!\n");
+		close( serverFd );
+		retVal = KErrGeneral;
+		}
+
+	if( KErrNone == retVal )
+		{
+		//Now Receive and Send some Data
+		for(TInt i=1; i<=count; i++)
+			{
+			TInt ret = recv(newFd, recvBuff, maxRecv, 0);
+			if( ret == -1 )
+				{
+				fprintf(logFile, "Socket recv Failed!!\n");
+				close( newFd );
+				close( serverFd );
+				retVal = KErrGeneral;
+				break;
+				}
+			fprintf(logFile, "Socket received %s\n", recvBuff);
+			sprintf(sendBuff, "%s %d", buff, i);
+			ret = send(newFd, sendBuff, sizeof(sendBuff), 0);
+			if( ret == -1 )
+				{
+				fprintf(logFile, "Socket send Failed!!\n");
+				close( newFd );
+				close( serverFd );
+				retVal = KErrGeneral;
+				break;
+				}
+			}
+		}
+	
+	if( KErrNone == retVal )
+		{
+		close( newFd );
+		close( serverFd );
+		}
+	fprintf(logFile, "Server Thread Completed with %d\n", retVal);
+	fclose(logFile);
+	return (void*)retVal;
+	}
+
+// -----------------------------------------------------------------------------
+// SocketWriteThreadEntryPoint
+// Thread Entry Function for Socket write thread
+// -----------------------------------------------------------------------------
+//
+void* SocketWriteThreadEntryPoint( void* aParam ) 
+	{
+	FILE* logFile;
+	TInt retVal = KErrNone;
+	TInt count = (TInt) aParam;
+
+	TInt portNum = KPortNum + count;
+	int clientFd;
+	size_t addrSize;
+	struct sockaddr_in servAddr;
+	const char* buff = "Client --> Sending Data Item : ";
+	char sendBuff[50];
+	char recvBuff[100];
+	const unsigned int maxRecv = 100;
+
+	IN_SET_LOOPBACK_ADDR( &servAddr );
+	servAddr.sin_port = htons( (unsigned short)portNum );
+
+	logFile = fopen(KThreadTwoLogFile, "w");
+	if(logFile == 0)
+		{
+		return (void*) KErrGeneral;
+		}
+
+	fprintf(logFile, "Client Socket Thread\n");
+
+	clientFd = socket(AF_INET, SOCK_STREAM, 0);
+	if( clientFd == -1 )
+		{
+		fprintf(logFile, "Socket creation Failed!!\n");
+		retVal = KErrGeneral;
+		}
+	
+	addrSize = sizeof(servAddr);
+	retVal = connect(clientFd, (struct sockaddr*)&servAddr, addrSize);
+	//This should Pass
+	if( retVal == -1 )
+		{
+		fprintf(logFile, "Socket connect Failed!!\n");
+		close(clientFd);
+		retVal = KErrGeneral;
+		}
+
+	if( KErrNone == retVal )
+		{
+		//Now Send and Receive some Data
+		for(TInt i=1; i<=count; i++)
+			{
+			sprintf(sendBuff, "%s %d", buff, i);
+			TInt ret = send(clientFd, sendBuff, sizeof(sendBuff), 0);
+			if(ret == -1)
+				{
+				fprintf(logFile, "Socket send Failed!!\n");
+				close( clientFd );
+				retVal = KErrGeneral;
+				break;
+				}
+			ret = recv(clientFd, recvBuff, maxRecv, 0);
+			if(ret == -1)
+				{
+				fprintf(logFile, "Socket recv Failed!!\n");
+				close( clientFd );
+				retVal = KErrGeneral;
+				break;
+				}
+			fprintf(logFile, "Socket received %s\n", recvBuff);
+			}
+		}
+
+	if (KErrNone == retVal )
+		{
+		close( clientFd );
+		}
+		
+	fprintf(logFile, "Client Thread Completed with %d\n", retVal);
+	fclose(logFile);
+	return (void*)retVal;
+	}
+
+// -----------------------------------------------------------------------------
+// FileReadThreadEntryPoint
+// Thread Entry Function for File read thread
+// -----------------------------------------------------------------------------
+//
+void* FileReadThreadEntryPoint( void* aParam )
+	{
+	TInt retVal = KErrNone;
+	char string[80];
+	int count = 0;
+	int index = 0;
+	TThreadParam* pThreadParam = ( TThreadParam* ) aParam;
+	FILE* fp = pThreadParam->iFp;
+
+	for( ;index < pThreadParam->iDataCount; index++ )
+		{
+		//Wait for the other thread to write some data to file
+		retVal = sem_wait(&pThreadParam->iSemaphore);
+		if( retVal != 0 )
+			{
+			retVal = KErrGeneral;
+			break;
+			}
+		fscanf(fp, "%s %d", string, &count);
+		}
+
+	return (void*)retVal;	
+	}
+	
+// -----------------------------------------------------------------------------
+// FileWriteThreadEntryPoint
+// Thread Entry Function for File write thread
+// -----------------------------------------------------------------------------
+//
+void* FileWriteThreadEntryPoint( void* aParam )
+	{
+	TInt retVal = KErrNone;
+	char string[] = "Writing some ASCII Data : ";
+	int index = 0;
+	TThreadParam* pThreadParam = ( TThreadParam* ) aParam;
+	FILE* fp = pThreadParam->iFp;
+	//Open the File in write mode
+
+	for( ;index < pThreadParam->iDataCount; index++ )
+		{
+		fprintf(fp, "%s %d", string, index);
+		//Tell the other thread that data is ready for reading
+		retVal = sem_post(&pThreadParam->iSemaphore);
+		if( retVal != 0 )
+			{
+			retVal = KErrGeneral;
+			break;
+			}
+		}
+
+	return (void*)retVal;	
+	}
+
+// -----------------------------------------------------------------------------
+// FileWriteThreadEntryPoint
+// Thread Entry Function for File write thread
+// -----------------------------------------------------------------------------
+//
+void* ServerLockThreadEntryPoint( void* /*aParam*/ )
+	{
+	const char* fileName = "c:\\Logs\\TestReport.txt";
+	TInt retVal = KErrNone;
+	struct stat buf;
+	retVal = stat(fileName, &buf);
+	return (void*)retVal;
+	}
+	
+//  End of File