Browse Source

- Implement quick file comparing routine

- Fix crash - wait on the threads themselves, not on Event objects.
  It takes time between the time a thread signals the event, and the
  time it actually terminates (shutdown code) - so FreeLibrary() and
  the main() termination could occur before all of the threads
  terminated...
PHP-4.0.5
Zeev Suraski 25 years ago
parent
commit
47ea52ca58
  1. 46
      sapi/isapi/stresstest/notes.txt
  2. 71
      sapi/isapi/stresstest/stresstest.cpp

46
sapi/isapi/stresstest/notes.txt

@ -1,46 +1,56 @@
This stress test program is for debugging threading issues with the isapi module.
This stress test program is for debugging threading issues with the ISAPI
module.
2 ways to use it.
2 ways to use it:
1: test any php script file on multiple threads
2: run the php test scripts bundled with the source code
GLOBAL SETTINGS
===============
If you need to set special environement variables, in addition to your regular environment, create a file that contains them, one setting per line:
If you need to set special environement variables, in addition to your
regular environment, create a file that contains them, one setting per line:
MY_ENV_VAR=XXXXXXXX
This can be used to simulate isapi environment variables if need be.
This can be used to simulate ISAPI environment variables if need be.
By default, stress test uses 10 threads. To change this, change the define NUM_THREADS in stresstest.cpp.
By default, stress test uses 10 threads. To change this, change the define
NUM_THREADS in stresstest.cpp.
1: test any php script file on multiple threads
Create a file that contains a list of php script files, one per line. If you need to provide input, place the GET data, or Query String, after the filename. File contents would look like:
1: Test any php script file on multiple threads
===============================================
Create a file that contains a list of php script files, one per line. If
you need to provide input, place the GET data, or Query String, after the
filename. File contents would look like:
e:\inetpub\pages\index.php
e:\inetpub\pages\info.php
e:\inetpub\pages\test.php a=1&b=2
run: stresstest L files.txt
Run: stresstest L files.txt
2: run the php test scripts bundled with the source code
supply the path to the parent of the "tests" directory
(expect a couple long pauses for a couple of the larger tests)
run: stresstest T c:\php4-source
2: Run the php test scripts bundled with the source code
========================================================
supply the path to the parent of the "tests" directory (expect a couple
long pauses for a couple of the larger tests)
TODO:
Run: stresstest T c:\php4-source
Make more options configurable: number of threads, itterations, etc.
Improve stdout output to make it more usefull
Implement support for SKIPIF
TODO:
Improve speed of CompareFile function (too slow on big files).
* Make more options configurable: number of threads, iterations, etc.
* Improve stdout output to make it more useful
* Implement support for SKIPIF
* Improve speed of CompareFile function (too slow on big files).

71
sapi/isapi/stresstest/stresstest.cpp

@ -31,7 +31,6 @@
//
#define NUM_THREADS 10
#define ITERATIONS 1
HANDLE terminate[NUM_THREADS];
HANDLE StartNow;
// quick and dirty environment
typedef CMapStringToString TEnvironment;
@ -101,32 +100,50 @@ void stripcrlf(char *line)
BOOL CompareFiles(const char*f1, const char*f2)
{
FILE *fp1 = fopen(f1,"r");
if (!fp1) return FALSE;
FILE *fp2 = fopen(f2,"r");
if (!fp2) {
FILE *fp1, *fp2;
bool retval;
char buf1[1024], buf2[1024];
int length1, length2;
if ((fp1=fopen(f1, "r"))==NULL) {
return FALSE;
}
if ((fp2=fopen(f2, "r"))==NULL) {
fclose(fp1);
return FALSE;
}
CString file1, file2, line;
char buf[1024];
while (fgets(buf, sizeof(buf), fp1)) {
line = buf;
line.TrimLeft();
line.TrimRight();
file1+=line;
retval = TRUE; // success oriented
while (true) {
length1 = fread(buf1, 1, sizeof(buf1), fp1);
length2 = fread(buf2, 1, sizeof(buf2), fp2);
buf2[0] = 0;
// 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);
while (fgets(buf, sizeof(buf), fp2)) {
line = buf;
line.TrimLeft();
line.TrimRight();
file2+=line;
}
fclose(fp2);
return file1==file2;
return retval;
}
BOOL ReadGlobalEnvironment(const char *environment)
@ -202,16 +219,13 @@ void DoThreads() {
DWORD tid;
HANDLE threads[NUM_THREADS];
for (DWORD i=0; i< NUM_THREADS; i++) {
terminate[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
if ((threads[i]=CreateThread(NULL, 0, IsapiThread, &terminate[i], CREATE_SUSPENDED, &tid))==NULL){
SetEvent(terminate[i]);
}
threads[i]=CreateThread(NULL, 0, IsapiThread, NULL, CREATE_SUSPENDED, &tid);
}
for (i=0; i< NUM_THREADS; i++) {
if (threads[i]) ResumeThread(threads[i]);
}
// wait for threads to finish
WaitForMultipleObjects(NUM_THREADS, terminate, TRUE, INFINITE);
WaitForMultipleObjects(NUM_THREADS, threads, TRUE, INFINITE);
}
void DoFileList(const char *filelist, const char *environment)
@ -394,7 +408,8 @@ void DoTestFiles(const char *filelist, const char *environment)
printf("Done\r\n");
}
int main(int argc, char* argv[]) {
int main(int argc, char* argv[])
{
LPVOID lpMsgBuf;
char *filelist=NULL, *environment=NULL;
@ -454,8 +469,9 @@ int main(int argc, char* argv[]) {
_snprintf(TestPath, sizeof(TestPath)-1, "%s\\tests", filelist);
else strcpy(TestPath, "tests");
DoTestFiles(TestPath, environment);
} else
} else {
DoFileList(filelist, environment);
}
// cleanup
@ -470,8 +486,8 @@ int main(int argc, char* argv[]) {
DWORD CALLBACK IsapiThread(void *p)
{
HANDLE *terminate = (HANDLE *)p;
DWORD filecount = IsapiFileList.GetSize();
for (DWORD j=0; j<ITERATIONS; j++) {
for (DWORD i=0; i<filecount; i++) {
// execute each file
@ -496,7 +512,6 @@ DWORD CALLBACK IsapiThread(void *p)
Sleep(10);
}
}
SetEvent(*terminate);
printf("Thread ending...\n");
return 0;
}

Loading…
Cancel
Save