?? stresstest.cpp
字號:
/* * ======================================================================= * * File: stress .c * * stress tester for isapi dll's * * based on cgiwrap * * ======================================================================= * **/#define WIN32_LEAN_AND_MEAN#include <afx.h>#include <afxtempl.h>#include <winbase.h>#include <winerror.h>#include <httpext.h>#include <stdio.h>#include <stdlib.h>#include "getopt.h"// These are things that go out in the Response Header//#define HTTP_VER "HTTP/1.0"#define SERVER_VERSION "Http-Srv-Beta2/1.0"//// Simple wrappers for the heap APIS//#define xmalloc(s) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (s))#define xfree(s) HeapFree(GetProcessHeap(), 0, (s))//// The mandatory exports from the ISAPI DLL//DWORD numThreads = 1;DWORD iterations = 1;HANDLE StartNow;// quick and dirty environmenttypedef CMapStringToString TEnvironment;TEnvironment IsapiEnvironment;typedef struct _TResults { LONG ok; LONG bad;} TResults;CStringArray IsapiFileList; // list of filenamesCStringArray TestNames; // --TEST--CStringArray IsapiGetData; // --GET--CStringArray IsapiPostData; // --POST--CStringArray IsapiMatchData; // --EXPECT--CArray<TResults, TResults> Results;typedef struct _TIsapiContext { HANDLE in; HANDLE out; DWORD tid; TEnvironment env; HANDLE waitEvent;} TIsapiContext;//// Prototypes of the functions this sample implements//extern "C" {HINSTANCE hDll;typedef BOOL (WINAPI *VersionProc)(HSE_VERSION_INFO *) ;typedef DWORD (WINAPI *HttpExtProc)(EXTENSION_CONTROL_BLOCK *);typedef BOOL (WINAPI *TerminateProc) (DWORD);BOOL WINAPI FillExtensionControlBlock(EXTENSION_CONTROL_BLOCK *, TIsapiContext *) ;BOOL WINAPI GetServerVariable(HCONN, LPSTR, LPVOID, LPDWORD );BOOL WINAPI ReadClient(HCONN, LPVOID, LPDWORD);BOOL WINAPI WriteClient(HCONN, LPVOID, LPDWORD, DWORD);BOOL WINAPI ServerSupportFunction(HCONN, DWORD, LPVOID, LPDWORD, LPDWORD);VersionProc IsapiGetExtensionVersion;HttpExtProc IsapiHttpExtensionProc;TerminateProc TerminateExtensionProc;HSE_VERSION_INFO version_info;}char * MakeDateStr(VOID);char * GetEnv(char *);DWORD CALLBACK IsapiThread(void *);int stress_main(const char *filename, const char *arg, const char *postfile, const char *matchdata);BOOL bUseTestFiles = FALSE;char temppath[MAX_PATH];void stripcrlf(char *line){ DWORD l = strlen(line)-1; if (line[l]==10 || line[l]==13) line[l]=0; l = strlen(line)-1; if (line[l]==10 || line[l]==13) line[l]=0;}#define COMPARE_BUF_SIZE 1024BOOL CompareFiles(const char*f1, const char*f2){ FILE *fp1, *fp2; bool retval; char buf1[COMPARE_BUF_SIZE], buf2[COMPARE_BUF_SIZE]; int length1, length2; if ((fp1=fopen(f1, "r"))==NULL) { return FALSE; } if ((fp2=fopen(f2, "r"))==NULL) { fclose(fp1); return FALSE; } retval = TRUE; // success oriented while (true) { length1 = fread(buf1, 1, sizeof(buf1), fp1); length2 = fread(buf2, 1, sizeof(buf2), fp2); // check for end of file if (feof(fp1)) { if (!feof(fp2)) { retval = FALSE; } break; } else if (feof(fp2)) { if (!feof(fp1)) { retval = FALSE; } break; } // compare data if (length1!=length2 || memcmp(buf1, buf2, length1)!=0) { retval = FALSE; break; } } fclose(fp1); fclose(fp2); return retval;}BOOL CompareStringWithFile(const char *filename, const char *str, unsigned int str_length){ FILE *fp; bool retval; char buf[COMPARE_BUF_SIZE]; unsigned int offset=0, readbytes; fprintf(stderr, "test %s\n",filename); if ((fp=fopen(filename, "rb"))==NULL) { fprintf(stderr, "Error opening %s\n",filename); return FALSE; } retval = TRUE; // success oriented while (true) { readbytes = fread(buf, 1, sizeof(buf), fp); // check for end of file if (offset+readbytes > str_length || memcmp(buf, str+offset, readbytes)!=NULL) { fprintf(stderr, "File missmatch %s\n",filename); retval = FALSE; break; } if (feof(fp)) { if (!retval) fprintf(stderr, "File zero length %s\n",filename); break; } } fclose(fp); return retval;}BOOL ReadGlobalEnvironment(const char *environment){ if (environment) { FILE *fp = fopen(environment, "r"); DWORD i=0; if (fp) { char line[2048]; while (fgets(line, sizeof(line)-1, fp)) { // file.php arg1 arg2 etc. char *p = strchr(line, '='); if (p) { *p=0; IsapiEnvironment[line]=p+1; } } fclose(fp); return IsapiEnvironment.GetCount() > 0; } } return FALSE;}BOOL ReadFileList(const char *filelist){ FILE *fp = fopen(filelist, "r"); if (!fp) { printf("Unable to open %s\r\n", filelist); } char line[2048]; int i=0; while (fgets(line, sizeof(line)-1, fp)) { // file.php arg1 arg2 etc. stripcrlf(line); if (strlen(line)>3) { char *p = strchr(line, ' '); if (p) { *p = 0; // get file IsapiFileList.Add(line); IsapiGetData.Add(p+1); } else { // just a filename is all IsapiFileList.Add(line); IsapiGetData.Add(""); } } // future use IsapiPostData.Add(""); IsapiMatchData.Add(""); TestNames.Add(""); i++; } Results.SetSize(TestNames.GetSize()); fclose(fp); return IsapiFileList.GetSize() > 0;}void DoThreads() { if (IsapiFileList.GetSize() == 0) { printf("No Files to test\n"); return; } printf("Starting Threads...\n"); // loop creating threads DWORD tid; HANDLE *threads = new HANDLE[numThreads]; DWORD i; for (i=0; i< numThreads; i++) { threads[i]=CreateThread(NULL, 0, IsapiThread, NULL, CREATE_SUSPENDED, &tid); } for (i=0; i< numThreads; i++) { if (threads[i]) ResumeThread(threads[i]); } // wait for threads to finish WaitForMultipleObjects(numThreads, threads, TRUE, INFINITE); for (i=0; i< numThreads; i++) { CloseHandle(threads[i]); } delete threads;}void DoFileList(const char *filelist, const char *environment){ // read config files if (!ReadFileList(filelist)) { printf("No Files to test!\r\n"); return; } ReadGlobalEnvironment(environment); DoThreads();}/** * ParseTestFile * parse a single phpt file and add it to the arrays */BOOL ParseTestFile(const char *path, const char *fn){ // parse the test file char filename[MAX_PATH]; _snprintf(filename, sizeof(filename)-1, "%s\\%s", path, fn); char line[1024]; memset(line, 0, sizeof(line)); CString cTest, cSkipIf, cPost, cGet, cFile, cExpect; printf("Reading %s\r\n", filename); enum state {none, test, skipif, post, get, file, expect} parsestate = none; FILE *fp = fopen(filename, "rb"); char *tn = _tempnam(temppath,"pht."); char *en = _tempnam(temppath,"exp."); FILE *ft = fopen(tn, "wb+"); FILE *fe = fopen(en, "wb+"); if (fp && ft && fe) { while (fgets(line, sizeof(line)-1, fp)) { if (line[0]=='-') { if (_strnicmp(line, "--TEST--", 8)==0) { parsestate = test; continue; } else if (_strnicmp(line, "--SKIPIF--", 10)==0) { parsestate = skipif; continue; } else if (_strnicmp(line, "--POST--", 8)==0) { parsestate = post; continue; } else if (_strnicmp(line, "--GET--", 7)==0) { parsestate = get; continue; } else if (_strnicmp(line, "--FILE--", 8)==0) { parsestate = file; continue; } else if (_strnicmp(line, "--EXPECT--", 10)==0) { parsestate = expect; continue; } } switch (parsestate) { case test: stripcrlf(line); cTest = line; break; case skipif: cSkipIf += line; break; case post: cPost += line; break; case get: cGet += line; break; case file: fputs(line, ft); break; case expect: fputs(line, fe); break; } } fclose(fp); fclose(ft); fclose(fe); if (!cTest.IsEmpty()) { IsapiFileList.Add(tn); TestNames.Add(cTest); IsapiGetData.Add(cGet); IsapiPostData.Add(cPost); IsapiMatchData.Add(en); free(tn); free(en); return TRUE; } } free(tn); free(en); return FALSE;}/** * GetTestFiles * Recurse through the path and subdirectories, parse each phpt file */BOOL GetTestFiles(const char *path){ // find all files .phpt under testpath\tests char FindPath[MAX_PATH]; WIN32_FIND_DATA fd; memset(&fd, 0, sizeof(WIN32_FIND_DATA)); _snprintf(FindPath, sizeof(FindPath)-1, "%s\\*.*", path); HANDLE fh = FindFirstFile(FindPath, &fd); if (fh != INVALID_HANDLE_VALUE) { do { if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && !strchr(fd.cFileName, '.')) { // subdirectory, recurse into it char NewFindPath[MAX_PATH]; _snprintf(NewFindPath, sizeof(NewFindPath)-1, "%s\\%s", path, fd.cFileName); GetTestFiles(NewFindPath); } else if (strstr(fd.cFileName, ".phpt")) { // got test file, parse it now if (ParseTestFile(path, fd.cFileName)) { printf("Test File Added: %s\\%s\r\n", path, fd.cFileName); } } memset(&fd, 0, sizeof(WIN32_FIND_DATA)); } while (FindNextFile(fh, &fd) != 0); FindClose(fh); } return IsapiFileList.GetSize() > 0;}void DeleteTempFiles(const char *mask){ char FindPath[MAX_PATH]; WIN32_FIND_DATA fd; memset(&fd, 0, sizeof(WIN32_FIND_DATA)); _snprintf(FindPath, sizeof(FindPath)-1, "%s\\%s", temppath, mask); HANDLE fh = FindFirstFile(FindPath, &fd); if (fh != INVALID_HANDLE_VALUE) { do { char NewFindPath[MAX_PATH]; _snprintf(NewFindPath, sizeof(NewFindPath)-1, "%s\\%s", temppath, fd.cFileName); DeleteFile(NewFindPath); memset(&fd, 0, sizeof(WIN32_FIND_DATA)); } while (FindNextFile(fh, &fd) != 0); FindClose(fh); }}void DoTestFiles(const char *filelist, const char *environment){ if (!GetTestFiles(filelist)) { printf("No Files to test!\r\n"); return; } Results.SetSize(IsapiFileList.GetSize()); ReadGlobalEnvironment(environment); DoThreads(); printf("\r\nRESULTS:\r\n"); // show results: DWORD r = Results.GetSize(); for (DWORD i=0; i< r; i++) { TResults result = Results.GetAt(i); printf("%s\r\nOK: %d FAILED: %d\r\n", TestNames.GetAt(i), result.ok, result.bad); } // delete temp files printf("Deleting Temp Files\r\n"); DeleteTempFiles("exp.*"); DeleteTempFiles("pht.*"); printf("Done\r\n");}#define OPTSTRING "m:f:d:h:t:i:"static void _usage(char *argv0){ char *prog; prog = strrchr(argv0, '/'); if (prog) { prog++; } else {
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -