// p4bridgeStressTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "CommandData.h"
#include "StrOps.h"
#include <conio.h>
int run = 10;
P4BridgeServer* pSrvr = NULL;
#define MAX_THREADS 6
char** AllFiles = NULL;
int AllFilesCnt = 0;
char * Port = NULL;
char * User = NULL;
char * Client = NULL;
char * ClientRoot = NULL;
// fstat each file in the workspace, one at a time
DWORD WINAPI BkThreadFunction0( LPVOID lpParam )
{
	UINT threadId = (UINT) lpParam;
	int cmdId = (threadId << 23) + 1;
	char* flags[1]  = {"-Olp"};
	int fileIdx = 0;
	while (run > 0)
	{
		CommandData* cmd = new CommandData( "fstat", flags, 1, &AllFiles[fileIdx], 1, 1);
		cmd->Run( pSrvr, cmdId );	
		ReleaseConnection(pSrvr, cmdId++, 10);	
		delete cmd;
		if (++fileIdx >= AllFilesCnt)
		{
			fileIdx = 0;
		}
	}
	return 0;
}
// fstat all file in the workspace, explicitely passing each and every depot path as a a parameter
DWORD WINAPI BkThreadFunction1( LPVOID lpParam )
{
	UINT threadId = (UINT) lpParam;
	int cmdId = (threadId << 23) + 1;
	//char* params[1]  = {"//depot/P4BridgeStressTest/..."};
	//CommandData* cmd = new CommandData( "files", NULL, 0, params, 1, 1);
	//printf("%X ", cmdId);
	//cmd->PrettyPrint();
	//if (!cmd->Run( pSrvr, cmdId ))
	//{ 
	//	printf("Command Failed!\r\n");
	//	return 0;
	//}
	//StrDictListIterator* results = GetTaggedOutput( pSrvr, cmdId );
	//AllFilesCnt = results?1:0;
	//
	//if (results)
	//{
	//	while (GetNextItem( results )) AllFilesCnt++;
	//}
	//R/CommandData* elease( results );
	////if (AllFilesCnt > 10000)
	////{
	////	AllFilesCnt = 10000;
	////}
	//results = GetTaggedOutput( pSrvr, cmdId );
	//if (results)
	//{
	//	AllFiles = new char*[AllFilesCnt];
	//	int idx = 0;
	//	while ((idx < AllFilesCnt) && GetNextItem( results )) 
	//	{
	//		KeyValuePair * pKv = NULL;
	//		while ((pKv = GetNextEntry( results )) != NULL)
	//		{
	//			const char * key = GetKey( pKv );
	//			const char * value = GetVare they ever going to alue( pKv );
	//			if (StrOps::StrCmp(key, "depotFile"))
	//			{
	//				AllFiles[idx++] = StrOps::StrDup(value);
	//			}
	//		}
	//	}
	//	AllFilesCnt = idx;
	//}
	//Release( results );
	//ReleaseConnection(pSrvr, cmdId++);
	//delete cmd;
	char* flags[1]  = {"-Olp"};
	
	CommandData* cmd = new CommandData( "fstat", flags, 1, AllFiles, AllFilesCnt, 1);
	while (run > 0)
	{
		cmd->Run( pSrvr, cmdId );	
		ReleaseConnection(pSrvr, cmdId++, 10);	
	}
	delete cmd;
	return 0;
}
// fstat all file in the workspace, using a ... wildcard
DWORD WINAPI BkThreadFunction2( LPVOID lpParam )
{
	UINT threadId = (UINT) lpParam;
	int cmdId = (threadId << 23) + 1;
	char* flags[1]  = {"-Olp"};
	char* params[1];
	params[0] = ClientRoot;
	CommandData* cmd = new CommandData( "fstat", flags, 1, params, 1, 1);
	while (run > 0)
	{
		cmd->Run( pSrvr, cmdId );	
		ReleaseConnection(pSrvr, cmdId++, 10);	
	}
	delete cmd;
	return 0;
}
// fstat all files in the workspace, 200 at a time, with individual paths as paramaters
DWORD WINAPI BkThreadFunction3( LPVOID lpParam )
{
	UINT threadId = (UINT) lpParam;
	int cmdId = (threadId << 23) + 1;
	char* flags[1]  = {"-Olp"};
	int fileIdx = 0;
	while (run > 0)
	{
		int paramCnt = 200;
		if ((AllFilesCnt - fileIdx) < 200)
		{
			paramCnt = AllFilesCnt - fileIdx;
		}
		CommandData* cmd = new CommandData( "fstat", flags, 1, &AllFiles[fileIdx], paramCnt, 1);
		cmd->Run( pSrvr, cmdId );	
		ReleaseConnection(pSrvr, cmdId++, 10);	
		delete cmd;
		fileIdx += 200;
		if (fileIdx >= AllFilesCnt)
		{
			fileIdx = 0;
		}
	}
	return 0;
}
// run an fstat on a bad path
DWORD WINAPI BkThreadFunction4( LPVOID lpParam )
{
	UINT threadId = (UINT) lpParam;
	int cmdId = (threadId << 23) + 1;
	char* flags[1]  = {"-Olp"};
	char* params[1]  = {"//depot/foo/bar/AintNoFileHere.cs"};
	CommandData* cmd = new CommandData( "fstat", flags, 1, params, 1, 1);
	while (run > 0)
	{
		cmd->Run( pSrvr, cmdId );	
		ReleaseConnection(pSrvr, cmdId++, 10);	
	}
	delete cmd;
	return 0;
}
// checkout each file in the workspace and then revert, one at a time
DWORD WINAPI BkThreadFunction5( LPVOID lpParam )
{
	UINT threadId = (UINT) lpParam;
	int cmdId = (threadId << 23) + 1;
	char* flags[3]  = {"-t", "-L", "-m 1000"};
	while (run > 0)
	{
		CommandData* cmd = new CommandData( "changes", flags, 3, NULL, 0, 0);
		cmd->Run( pSrvr, cmdId );	
		ReleaseConnection(pSrvr, cmdId++, 10);	
		delete cmd;
	}
	return 0;
}
// checkout each file in the workspace and then revert, one at a time
DWORD WINAPI BkThreadFunction6( LPVOID lpParam )
{
	UINT threadId = (UINT) lpParam;
	int cmdId = (threadId << 23) + 1;
	char* flags[1]  = {"-m 1000"};
	while (run > 0)
	{
		CommandData* cmd = new CommandData( "opened", flags, 1, NULL, 0, 0);
		cmd->Run( pSrvr, cmdId );	
		ReleaseConnection(pSrvr, cmdId++, 10);	
		delete cmd;
	}
	return 0;
}
#define NUM_THREADPROCS 7
LPTHREAD_START_ROUTINE threadProcs[NUM_THREADPROCS];
int main(int argc, char* argv[], char *envp[])
{
	FILE* f = fopen("test.ini", "r");
	if (f)
	{
		char buff[256];
		if (fscanf(f, "%s", buff))
		{
			Port = StrOps::StrDup(buff);
		}
		if (fscanf(f, "%s", buff))
		{
			User = StrOps::StrDup(buff);
		}
		if (fscanf(f, "%s", buff))
		{
			Client = StrOps::StrDup(buff);
		}
		if (fscanf(f, "%s", buff))
		{
			ClientRoot = StrOps::StrDup(buff);
		}
		fclose(f);
	}
	else
	{
		for (int idx = 0; idx < argc; idx++)
		{
			if (StrOps::StrCmp(argv[idx],"-p"))
			{
				Port = StrOps::StrDup(argv[++idx]);
			}
			if (StrOps::StrCmp(argv[idx],"-u"))
			{
				User = StrOps::StrDup(argv[++idx]);
			}
			if (StrOps::StrCmp(argv[idx],"-c"))
			{
				Client = StrOps::StrDup(argv[++idx]);
			}
			if (StrOps::StrCmp(argv[idx],"-r"))
			{
				ClientRoot = StrOps::StrDup(argv[++idx]);
			}
		}
	}
	if (!Port)
	{
		Port = StrOps::StrDup("qaplay:1999");
	}
	if (!User)
	{
		User = StrOps::StrDup("P4BridgeStressTest");
	}
	if (!Client)
	{
		Client = StrOps::StrDup("P4BridgeStressTest");
	}
	if (!ClientRoot)
	{
		ClientRoot = StrOps::StrDup("//depot/P4BridgeStressTest/...");
	}
	threadProcs[0] = BkThreadFunction0;
	threadProcs[1] = BkThreadFunction1;
	threadProcs[2] = BkThreadFunction2;
	threadProcs[3] = BkThreadFunction3;
	threadProcs[4] = BkThreadFunction4;
	threadProcs[5] = BkThreadFunction5;
	threadProcs[6] = BkThreadFunction6;
	DWORD dwThreadIdArray[MAX_THREADS];
	HANDLE hThreadArray[MAX_THREADS];
	pSrvr = Connect(Port, 
					User, 
					NULL,
					Client,
					NULL);
	// get the depot paths for all files in the workspace.
	int cmdId = (255 << 23) + 1;
	char* params[1];
	params[0] = ClientRoot;
	CommandData* cmd = new CommandData( "files", NULL, 0, params, 1, 1);
	cmd->Run( pSrvr, cmdId );
	StrDictListIterator* results = GetTaggedOutput( pSrvr, cmdId );
	//count the files returned
	AllFilesCnt = results?1:0;
	
	if (results)
	{
		while (GetNextItem( results )) AllFilesCnt++;
	}
	Release( results );
		
	//if (AllFilesCnt > 10000)
	//{
	//	AllFilesCnt = 10000;
	//}
	// now copy the depot paths for thos files into an array
	results = GetTaggedOutput( pSrvr, cmdId );
	if (results)
	{
		AllFiles = new char*[AllFilesCnt];
		int idx = 0;
		while ((idx < AllFilesCnt) && GetNextItem( results )) 
		{
			KeyValuePair * pKv = NULL;
			while ((pKv = GetNextEntry( results )) != NULL)
			{
				const char * key = GetKey( pKv );
				const char * value = GetValue( pKv );
				if (StrOps::StrCmp(key, "depotFile"))
				{
					AllFiles[idx++] = StrOps::StrDup(value);
				}
			}
		}
		AllFilesCnt = idx;
	}
	Release( results );
	ReleaseConnection(pSrvr, cmdId, 10);
	delete cmd;
	for( UINT i=0; i<MAX_THREADS; i++ )
	{
		int tpIdx = i;
		if (i >= NUM_THREADPROCS)
		{
			tpIdx = 0;
		}
		hThreadArray[i] = CreateThread(
			NULL,					//defaultsecurityattributes
			0,						//usedefaultstacksize
			threadProcs[tpIdx],		//threadfunctionname
			(void*) i,				//argumenttothreadfunction
			0,						//usedefaultcreationflags
			&(dwThreadIdArray[i]));	//returnsthethreadidentifier
		//Checkthereturnvalueforsuccess.
		//IfCreateThreadfails,terminateexecution.
		//Thiswillautomaticallycleanupthreadsandmemory.
		if (hThreadArray[i] == NULL)
		{
			ExitProcess(3);
		}
	}
	//while (--run)
	//{
	//	printf("run: %d\r\n", run);
	//	Sleep(1000);
	//}
    printf("Hit any key to halt threads");
    _getch();
    printf("\r\nWaiting for all threads to exit\r\n");
	run = 0;
	WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
	for(int i=0; i<MAX_THREADS; i++)
	{
		CloseHandle(hThreadArray[i]);
	}
	CloseConnection( pSrvr );
	if (AllFiles)
	{
		int idx = 0;
		for (int idx = 0; idx < AllFilesCnt; idx++) 
		{
			delete[] AllFiles[idx];
		}
		delete[] AllFiles;
	}
	if (Port)
	{
		delete[] Port;
	}
	if (User)
	{
		delete[] User;
	}
	if (Client)
	{
		delete[] Client;
	}
	if (ClientRoot)
	{
		delete[] ClientRoot;
	}
	 
	delete pSrvr;
    printf("Hit any key to exit");
    _getch();
	
	return 0;
}
                    | # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #3 | 28480 | eskopljak | submit | ||
| #2 | 28479 | eskopljak | submit | ||
| #1 | 28441 | eskopljak | Merging using p4api.net_branch | ||
| //guest/perforce_software/p4api-net/main/p4bridgeStressTest/p4bridgeStressTest.cpp | |||||
| #1 | 19044 | Norman Morse | 
                    Update workshop source from Perforce internal. 2016.1 release of P4API.NET  | 
                ||