Commit:    f8a1baf80706ba04d9f108be191af0614bed7396
Author:    Matt Ficken <v-maf...@microsoft.com>         Mon, 1 Apr 2013 
12:10:11 -0700
Parents:   456f9622e1c1ccdbf72a8ff1a44f007f582dae30
Branches:  master

Link:       
http://git.php.net/?p=pftt2.git;a=commitdiff;h=f8a1baf80706ba04d9f108be191af0614bed7396

Log:
fixing bug with ERROR_REPORTING directive


Former-commit-id: ac8d89d549d52695e4463b1971c921d2050c56a7

Changed paths:
  M  bin/pftt_shell.cmd
  A  bin/rctest.cmd
  M  src/com/github/mattficken/io/ArrayUtil.java
  M  src/com/mostc/pftt/host/AHost.java
  M  src/com/mostc/pftt/main/PfttMain.java
  M  src/com/mostc/pftt/model/core/PhpBuild.java
  M  src/com/mostc/pftt/model/core/PhpIni.java
  M  src/com/mostc/pftt/model/core/PhptSourceTestPack.java
  M  src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java
  M  src/com/mostc/pftt/model/sapi/ApacheManager.java
  M  src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java
  M  src/com/mostc/pftt/model/sapi/CrashedWebServerInstance.java
  M  src/com/mostc/pftt/model/sapi/IISManager.java
  M  src/com/mostc/pftt/model/sapi/SAPIInstance.java
  M  src/com/mostc/pftt/model/sapi/WebServerInstance.java
  M  src/com/mostc/pftt/model/smoke/RequiredExtensionsSmokeTest.java
  M  src/com/mostc/pftt/model/ui/UITestRunner.java
  M  src/com/mostc/pftt/model/ui/WordpressTestPack.java
  M  src/com/mostc/pftt/results/LocalConsoleManager.java
  M  src/com/mostc/pftt/results/PhpResultPackReader.java
  M  src/com/mostc/pftt/results/PhpResultPackWriter.java
  M  src/com/mostc/pftt/results/PhpUnitTestResult.java
  M  src/com/mostc/pftt/results/PhptTestResult.java
  M  src/com/mostc/pftt/results/UITestWriter.java
  M  src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
  M  src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java
  M  src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java
  M  src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java
  M  src/com/mostc/pftt/runner/AbstractTestCaseRunner.java
  M  src/com/mostc/pftt/runner/CliPhpUnitTestCaseRunner.java
  M  src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
  M  src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java
  M  src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java
  M  src/com/mostc/pftt/scenario/BuiltinWebServerScenario.java
  M  src/com/mostc/pftt/scenario/OpcacheScenario.java
  M  src/com/mostc/pftt/scenario/WinCacheScenario.java
  M  src/com/mostc/pftt/ui/ExpectedActualDiffPHPTDisplay.java
  M  src/com/mostc/pftt/util/EMailUtil.java
  M  src/com/mostc/pftt/util/WinDebugManager.java
  M  src/org/columba/ristretto/smtp/SMTPProtocol.java

diff --git a/bin/pftt_shell.cmd b/bin/pftt_shell.cmd
index 76dca0a..d16fcd7 100644
--- a/bin/pftt_shell.cmd
+++ b/bin/pftt_shell.cmd
@@ -15,7 +15,7 @@ ECHO Command Aliases:
 ECHO core_all      core_named    core_list  ca cn cl
 ECHO app_all       all_named     app_list   aa an al
 ECHO ui_all        ui_named      ui_list    ua un ul
-ECHO release_get   release_list  rl    rg   rgn   rgp
+ECHO release_get   release_list  rl    rg   rgn   rgp rctest
 @ECHO.
 ECHO Cleanup: 
 ECHO tka_apache    tka_php     tka_windbg     `net use`
diff --git a/bin/rctest.cmd b/bin/rctest.cmd
new file mode 100644
index 0000000..bf92395
--- /dev/null
+++ b/bin/rctest.cmd
@@ -0,0 +1,7 @@
+REM runs all tests on an RC build to make sure the binary is ready for 
production use
+
+REM rctest <ts build>;<nts build> <phpt test pack>
+
+REM core_all,app_all: 30 scenario sets (+6 for IIS-Standard, +6 for IIS 
express)
+REM ui_all: 12 scenario sets (+3 for IIS-Standard, +3 for IIS express)
+pftt -c 
apache,cli,builtin_web,deduplication,dfs,localfs,opcache,no_code_cache,symfony,joomla,wordpress
 -no_result_file_for_pass_xskip_skip core_all,app_all,ui_all %*
diff --git a/src/com/github/mattficken/io/ArrayUtil.java 
b/src/com/github/mattficken/io/ArrayUtil.java
index 8a71b0b..d604576 100644
--- a/src/com/github/mattficken/io/ArrayUtil.java
+++ b/src/com/github/mattficken/io/ArrayUtil.java
@@ -83,6 +83,12 @@ public class ArrayUtil {
                
                return clazz == null ? null : (E[]) 
out.toArray((E[])Array.newInstance(clazz, out.size()));
        }
+       
+       public static <E extends Object> List<E> toList(E e) {
+               ArrayList<E> o = new ArrayList<E>(1);
+               o.add(e);
+               return o;
+       }
 
        public static <E extends Object> List<E> toList(Collection<E> c) {
                if (c instanceof List)
diff --git a/src/com/mostc/pftt/host/AHost.java 
b/src/com/mostc/pftt/host/AHost.java
index 7f7f4fd..185f861 100644
--- a/src/com/mostc/pftt/host/AHost.java
+++ b/src/com/mostc/pftt/host/AHost.java
@@ -395,6 +395,9 @@ public abstract class AHost extends Host {
                public boolean isCrashedOrDebuggedAndClosed() {
                        return isCrashExitCode(AHost.this, getExitCode(), true);
                }
+               public boolean isCrashedAndDebugged() {
+                       return isDebuggerAttachedExitCode(AHost.this, 
getExitCode());
+               }
                /** immediately returns the output the process has returned (if 
process is still running, it may
                 * return more output after this call)
                 * 
@@ -452,6 +455,14 @@ public abstract class AHost extends Host {
                return exit_code != 0;
        } // end public static boolean isCrashExitCode
        
+       public static boolean isDebuggerAttachedExitCode(AHost host, int 
exit_code) {
+               if (host.isWindows()) {
+                       return exit_code == NTStatus.STATUS_DEBUGGER_INACTIVE;
+               } else {
+                       return false;
+               }
+       }
+       
        /** guesses a status code as a String for the exit code, or returns null
         * 
         * @param host
diff --git a/src/com/mostc/pftt/main/PfttMain.java 
b/src/com/mostc/pftt/main/PfttMain.java
index ca22eb0..c82a1be 100644
--- a/src/com/mostc/pftt/main/PfttMain.java
+++ b/src/com/mostc/pftt/main/PfttMain.java
@@ -71,6 +71,9 @@ import 
com.mostc.pftt.util.WindowsSnapshotDownloadUtil.FindBuildTestPackPair;
  * 
  */
 
+// TODO check all usage of System.exit
+// TODO check symfony thread safety
+//
 // TODO UI testing
 // commit: UI testing support, first implemented for Wordpress
 //
@@ -1292,14 +1295,17 @@ public class PfttMain {
                                
                                cmd_help();
                        } else if (command.equals("cmp-report")) {
-                               PhpResultPack base_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-5.3.24RC1-TS-X86-VC9"));
-                               PhpResultPack test_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-5.3.24RC1-TS-X86-VC9"));
+                               //PhpResultPack base_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-5.3.24RC1-TS-X86-VC9"));
+                               //PhpResultPack test_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-5.3.24RC1-TS-X86-VC9"));
+                               PhpResultPack base_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-rfe2612d-nTS-X86-VC9"));
+                               PhpResultPack test_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-rfecce5a-nTS-X86-VC9"));
+                               
                                //PhpResultPack base_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-5.4.14RC1-NTS-X86-VC9"));
                                //PhpResultPack test_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-5.4.14RC1-NTS-X86-VC9"));
-                               //PhpResultPack base_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-re9f996c-NTS-X86-VC9"));
-                               //PhpResultPack test_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-r85e5e60-NTS-X86-VC9"));
-                               //PhpResultPack base_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-rf3ebb40-NTS-X86-VC11"));
-                               //PhpResultPack test_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-r5d535a0-NTS-X86-VC11"));
+                               //PhpResultPack base_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-ref93a93-TS-X86-VC9"));
+                               //PhpResultPack test_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-r72426a4-TS-X86-VC9"));
+                               //PhpResultPack base_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-rbed44e5-NTS-X86-VC11"));
+                               //PhpResultPack test_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-r586dc07-NTS-X86-VC11"));
                                //PhpResultPack base_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-5.5.0beta1-TS-X86-VC11"));
                                //PhpResultPack test_pack = 
PhpResultPackReader.open(cm, rt.host, new 
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-5.5.0beta2-TS-X86-VC11"));
                                
diff --git a/src/com/mostc/pftt/model/core/PhpBuild.java 
b/src/com/mostc/pftt/model/core/PhpBuild.java
index e921c73..78765e9 100644
--- a/src/com/mostc/pftt/model/core/PhpBuild.java
+++ b/src/com/mostc/pftt/model/core/PhpBuild.java
@@ -475,6 +475,38 @@ public class PhpBuild extends SAPIManager {
                return branch;
        }
        
+       public boolean is53(ConsoleManager cm, Host host) {
+               try {
+                       return getVersionBranch(cm, host) == 
EBuildBranch.PHP_5_3;
+               } catch ( Exception ex ) {
+                       return false;
+               }
+       }
+       
+       public boolean is54(ConsoleManager cm, Host host) {
+               try {
+                       return getVersionBranch(cm, host) == 
EBuildBranch.PHP_5_4;
+               } catch ( Exception ex ) {
+                       return false;
+               }
+       }
+       
+       public boolean is55(ConsoleManager cm, Host host) {
+               try {
+                       return getVersionBranch(cm, host) == 
EBuildBranch.PHP_5_5;
+               } catch ( Exception ex ) {
+                       return false;
+               }
+       }
+       
+       public boolean is56(ConsoleManager cm, Host host) {
+               try {
+                       return getVersionBranch(cm, host) == 
EBuildBranch.PHP_5_6;
+               } catch ( Exception ex ) {
+                       return false;
+               }
+       }
+       
        /** checks to see if the extension is enabled or statically builtin to 
this build
         *  
         *  Note that PhpIni#hasExtension only checks to see if the extension 
is enabled in a PhpIni whereas
diff --git a/src/com/mostc/pftt/model/core/PhpIni.java 
b/src/com/mostc/pftt/model/core/PhpIni.java
index 141d8e3..ad9f1cc 100644
--- a/src/com/mostc/pftt/model/core/PhpIni.java
+++ b/src/com/mostc/pftt/model/core/PhpIni.java
@@ -65,6 +65,7 @@ public class PhpIni {
        public static final String U_INVALID_SUBSTITUTE = 
"U_INVALID_SUBSTITUTE";
        public static final String DOT_HTML = ".html";
        public static final String E_ALL_NOTICE_WARNING = "E_ALL | E_NOTICE | 
E_WARNING";
+       public static final String E_ALL_STRICT = "E_ALL | E_STRICT";
        //
        private static String dllName(String name) {
                // FUTURE macos x and solaris support
diff --git a/src/com/mostc/pftt/model/core/PhptSourceTestPack.java 
b/src/com/mostc/pftt/model/core/PhptSourceTestPack.java
index 55d5f73..6ab45ee 100644
--- a/src/com/mostc/pftt/model/core/PhptSourceTestPack.java
+++ b/src/com/mostc/pftt/model/core/PhptSourceTestPack.java
@@ -88,7 +88,11 @@ public class PhptSourceTestPack implements 
SourceTestPack<PhptActiveTestPack, Ph
                host.deleteFileExtension(test_pack, ".skip.php");
                host.deleteFileExtension(test_pack, ".cmd");
                host.deleteFileExtension(test_pack, ".sh");
-               host.deleteFileExtension(test_pack, ".php");
+               // don't delete .php (specifically run-test.php) in root of 
test-pack (user may want it later)
+               host.deleteFileExtension(test_pack+"/ext", ".php");
+               host.deleteFileExtension(test_pack+"/tests", ".php");
+               host.deleteFileExtension(test_pack+"/zend", ".php");
+               host.deleteFileExtension(test_pack+"/sapi", ".php");
        }
        
        public void read(List<PhptTestCase> test_cases, List<String> names, 
ConsoleManager cm, PhpResultPackWriter twriter, PhpBuild build) throws 
FileNotFoundException, IOException, Exception {
diff --git 
a/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java 
b/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java
index ac5185d..e2336f4 100644
--- 
a/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java
+++ 
b/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java
@@ -103,11 +103,14 @@ public abstract class 
AbstractManagedProcessesWebServerManager extends WebServer
                                {
                                        Socket sock = null;
                                        boolean connected = false;
-                                       for ( int i=0 ; i < 3 ; i++ ) {
+                                       long start_time = 
System.currentTimeMillis();
+                                       int socket_attempts;
+                                       // builtin web server needs many 
attempts and large timeouts
+                                       for ( socket_attempts=0 ; 
socket_attempts < 10 ; socket_attempts++ ) {
                                                connected = false;
                                                try {
                                                        sock = new Socket();
-                                                       
sock.setSoTimeout(100*(i+1));
+                                                       
sock.setSoTimeout(Math.min(60000, 100*((int)(Math.pow(socket_attempts+1, 
socket_attempts+1)))));
                                                        sock.connect(new 
InetSocketAddress(listen_address, port));
                                                        if (sock.isConnected()) 
{
                                                                connected = 
true;
@@ -120,7 +123,7 @@ public abstract class 
AbstractManagedProcessesWebServerManager extends WebServer
                                        }
                                        if (!connected) {
                                                // kill server and try again
-                                               throw new IOException("socket 
not connected");
+                                               throw new IOException("Could 
not socket to web server after it was started. Web server did not respond to 
socket. Tried "+socket_attempts+" times, waiting 
"+(System.currentTimeMillis()-start_time)+" millis total.");
                                        }
                                }
                                //
@@ -173,7 +176,7 @@ public abstract class 
AbstractManagedProcessesWebServerManager extends WebServer
                } // end for
                
                // fallback
-               sapi_output += "PFTT: wasn't able to start web server instance 
(after "+total_attempts+" attempts)... giving up.\n";
+               sapi_output = "PFTT: could not start web server instance (after 
"+total_attempts+" attempts)... giving up.\n" + sapi_output;
                
                // return this failure message to client code
                return new CrashedWebServerInstance(this, ini, env, 
sapi_output);
@@ -197,6 +200,11 @@ public abstract class 
AbstractManagedProcessesWebServerManager extends WebServer
                }
                
                @Override
+               public boolean isCrashedAndDebugged() {
+                       return process.isCrashedAndDebugged();
+               }
+               
+               @Override
                public void notifyCrash(String output, int exit_code) {
                        if (output==null)
                                output = "PFTT: web server started with: "+cmd;
diff --git a/src/com/mostc/pftt/model/sapi/ApacheManager.java 
b/src/com/mostc/pftt/model/sapi/ApacheManager.java
index 2300dd8..6ef589e 100644
--- a/src/com/mostc/pftt/model/sapi/ApacheManager.java
+++ b/src/com/mostc/pftt/model/sapi/ApacheManager.java
@@ -265,22 +265,23 @@ public class ApacheManager extends 
AbstractManagedProcessesWebServerManager {
                final String cmdline = httpd+" -X -f 
"+host.fixPath(apache_conf_file);
                
                // @see #createWebServerInstance for where command is executed 
to create httpd.exe process
-               return new ApacheWebServerInstance(apache_version, this, 
docroot, cmdline, ini, env, listen_address, port, host, conf_dir, 
apache_conf_file, error_log);
+               return new ApacheWebServerInstance(apache_version, this, 
docroot, cmdline, ini, env, listen_address, port, host, conf_dir, 
apache_conf_file, error_log, conf_str);
        } // end protected ManagedProcessWebServerInstance 
createManagedProcessWebServerInstance
        
        public class ApacheWebServerInstance extends 
ManagedProcessWebServerInstance {
-               protected final String conf_dir, apache_conf_file, error_log;
+               protected final String conf_dir, apache_conf_file, conf_str, 
error_log;
                protected final AHost host;
                protected final EApacheVersion apache_version;
                protected WeakReference<String> log_ref;
                
-               public ApacheWebServerInstance(EApacheVersion apache_version, 
ApacheManager ws_mgr, String docroot, String cmd, PhpIni ini, 
Map<String,String> env, String hostname, int port, AHost host, String conf_dir, 
String apache_conf_file, String error_log) {
+               public ApacheWebServerInstance(EApacheVersion apache_version, 
ApacheManager ws_mgr, String docroot, String cmd, PhpIni ini, 
Map<String,String> env, String hostname, int port, AHost host, String conf_dir, 
String apache_conf_file, String error_log, String conf_str) {
                        super(ws_mgr, docroot, cmd, ini, env, hostname, port);
                        this.apache_version = apache_version;
                        this.host = host;
                        this.conf_dir = conf_dir;
                        this.apache_conf_file = apache_conf_file;
                        this.error_log = error_log;
+                       this.conf_str = conf_str;
                }
                
                @Override
@@ -342,6 +343,11 @@ public class ApacheManager extends 
AbstractManagedProcessesWebServerManager {
                                return StringUtil.EMPTY;
                        }
                }
+
+               @Override
+               public String getSAPIConfig() {
+                       return conf_str;
+               }
                
        } // end public class ApacheWebServerInstance
        
diff --git a/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java 
b/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java
index cb6eb34..89aa3a5 100644
--- a/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java
+++ b/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java
@@ -68,6 +68,11 @@ public class BuiltinWebServerManager extends 
AbstractManagedProcessesWebServerMa
                                return StringUtil.EMPTY;
                        }
                }
+
+               @Override
+               public String getSAPIConfig() {
+                       return null;
+               }
                
        } // end public static class BuiltinWebServerInstance
        
diff --git a/src/com/mostc/pftt/model/sapi/CrashedWebServerInstance.java 
b/src/com/mostc/pftt/model/sapi/CrashedWebServerInstance.java
index 81f24cc..b205677 100644
--- a/src/com/mostc/pftt/model/sapi/CrashedWebServerInstance.java
+++ b/src/com/mostc/pftt/model/sapi/CrashedWebServerInstance.java
@@ -79,8 +79,17 @@ public class CrashedWebServerInstance extends 
WebServerInstance {
 
        @Override
        public String getDocroot() {
-               // TODO Auto-generated method stub
                return null;
        }
 
-}
+       @Override
+       public String getSAPIConfig() {
+               return null;
+       }
+
+       @Override
+       public boolean isCrashedAndDebugged() {
+               return false;
+       }
+
+} // end public class CrashedWebServerInstance
diff --git a/src/com/mostc/pftt/model/sapi/IISManager.java 
b/src/com/mostc/pftt/model/sapi/IISManager.java
index c9fcdff..ffd68a4 100644
--- a/src/com/mostc/pftt/model/sapi/IISManager.java
+++ b/src/com/mostc/pftt/model/sapi/IISManager.java
@@ -271,6 +271,18 @@ public class IISManager extends WebServerManager {
                        // TODO Auto-generated method stub
                        return null;
                }
+
+               @Override
+               public String getSAPIConfig() {
+                       // TODO Auto-generated method stub
+                       return null;
+               }
+
+               @Override
+               public boolean isCrashedAndDebugged() {
+                       // TODO Auto-generated method stub
+                       return false;
+               }
                
        } // end public class IISWebServerInstance
 
diff --git a/src/com/mostc/pftt/model/sapi/SAPIInstance.java 
b/src/com/mostc/pftt/model/sapi/SAPIInstance.java
index d8c0cd3..6072432 100644
--- a/src/com/mostc/pftt/model/sapi/SAPIInstance.java
+++ b/src/com/mostc/pftt/model/sapi/SAPIInstance.java
@@ -14,4 +14,5 @@ public abstract class SAPIInstance {
        public abstract boolean isRunning();
        public abstract String getInstanceInfo(ConsoleManager cm);
        public abstract boolean isCrashedOrDebuggedAndClosed();
+       public abstract String getSAPIConfig();
 }
diff --git a/src/com/mostc/pftt/model/sapi/WebServerInstance.java 
b/src/com/mostc/pftt/model/sapi/WebServerInstance.java
index 17d0302..e9b4598 100644
--- a/src/com/mostc/pftt/model/sapi/WebServerInstance.java
+++ b/src/com/mostc/pftt/model/sapi/WebServerInstance.java
@@ -67,7 +67,7 @@ public abstract class WebServerInstance extends SAPIInstance {
                        return sapi_output;
                }
        }
-       
+               
        /** handles reporting an instance that crashed
         * 
         * @param output - any output server returned when it crashed (or null)
@@ -93,7 +93,7 @@ public abstract class WebServerInstance extends SAPIInstance {
                        
                        // if crash, record output with all tests that were 
running during crash
                        crashed = true;
-                       
+                                               
                        StringBuilder sb = new StringBuilder(1024);
                        
                        sb.append("PFTT: web server crashed with exit code: 
"+exit_code+" status="+AHost.guessExitCodeStatus(null, exit_code)+" \n");
@@ -172,7 +172,7 @@ public abstract class WebServerInstance extends 
SAPIInstance {
                }
        }
        
-       /** returns TRUE if this web server crashed
+       /** returns TRUE if this web server crashed OR crashed and debugged
         * 
         * @return
         */
@@ -183,6 +183,12 @@ public abstract class WebServerInstance extends 
SAPIInstance {
                }
        }
        
+       /** returns TRUE if this web server is crashed AND debugged
+        * 
+        * @return
+        */
+       public abstract boolean isCrashedAndDebugged();
+       
        public abstract String hostname();
        public abstract int port();
 
diff --git a/src/com/mostc/pftt/model/smoke/RequiredExtensionsSmokeTest.java 
b/src/com/mostc/pftt/model/smoke/RequiredExtensionsSmokeTest.java
index c3e0ab4..125f900 100644
--- a/src/com/mostc/pftt/model/smoke/RequiredExtensionsSmokeTest.java
+++ b/src/com/mostc/pftt/model/smoke/RequiredExtensionsSmokeTest.java
@@ -137,7 +137,14 @@ public class RequiredExtensionsSmokeTest extends SmokeTest 
{
                
                //
                // CRITICAL
-               ini.putMulti(PhpIni.ERROR_REPORTING, 
PhpIni.E_ALL_NOTICE_WARNING);
+               // be very careful changing ERROR_REPORTING. it can cause false 
failures.
+               // WHENEVER changing this setting, you MUST test a ts and nts 
build from 5.3, 5.4, 5.5 with at least CLI and Apache scenarios
+               // before AND after to make sure this didn't break anything. 
PHPT tests are especially sensitive to this setting (can cause false PHPT 
failures).
+               // 
+               // testing 5.3 is especially important
+               //
+               // NOTE: 5.3 php builds do not include E_STRICT with E_ALL. you 
must explicitly include both here!
+               ini.putMulti(PhpIni.ERROR_REPORTING, build.is53(cm, 
host)?PhpIni.E_ALL_STRICT:PhpIni.E_ALL_NOTICE_WARNING);
                // CRITICAL
                ini.putMulti(PhpIni.DISPLAY_ERRORS, PhpIni.ON);
                // CRITICAL
diff --git a/src/com/mostc/pftt/model/ui/UITestRunner.java 
b/src/com/mostc/pftt/model/ui/UITestRunner.java
index 63ae34d..cc57b6b 100644
--- a/src/com/mostc/pftt/model/ui/UITestRunner.java
+++ b/src/com/mostc/pftt/model/ui/UITestRunner.java
@@ -73,7 +73,7 @@ public class UITestRunner implements IUITestBranch {
                                        LocalHost host = new LocalHost();
                                        build.open(cm, host);
                                        PhpResultPackWriter tmgr = new 
PhpResultPackWriter(host, cm, new File("c:/php-sdk"), build);
-                               UITestRunner test = new UITestRunner(null, 
"http://10.200.51.109";, host, ScenarioSet.getDefaultScenarioSets().get(0), 
tmgr, test_pack);
+                               UITestRunner test = new UITestRunner(null, 
"http://192.168.1.73/";, host, ScenarioSet.getDefaultScenarioSets().get(0), 
tmgr, test_pack);
                                test.setUp();
                                // TODO new MediaWikiUITestPack().run(test);
                                test_pack.run(test);
@@ -163,7 +163,7 @@ public class UITestRunner implements IUITestBranch {
                                try {
                                        tests.add(clazz.newInstance());
                                } catch ( Exception ex ) {
-                                       runner.tmgr.addResult(runner.this_host, 
runner.this_scenario_set, clazz.getSimpleName(), ErrorUtil.toString(ex), 
EUITestStatus.TEST_EXCEPTION, null, runner.test_pack);
+                                       // TODO 
runner.tmgr.addResult(runner.this_host, runner.this_scenario_set, 
clazz.getSimpleName(), ErrorUtil.toString(ex), EUITestStatus.TEST_EXCEPTION, 
null, runner.test_pack);
                                        return new 
DummyUITestRunner(EUITestStatus.TEST_EXCEPTION, user_account);
                                }
                        }
@@ -171,7 +171,7 @@ public class UITestRunner implements IUITestBranch {
                                try {
                                        cleanup_test = 
cleanup_clazz.newInstance();
                                } catch ( Exception ex ) {
-                                       runner.tmgr.addResult(runner.this_host, 
runner.this_scenario_set, cleanup_clazz.getSimpleName(), 
ErrorUtil.toString(ex), EUITestStatus.TEST_EXCEPTION, null, runner.test_pack);
+                                       // TODO 
runner.tmgr.addResult(runner.this_host, runner.this_scenario_set, 
cleanup_clazz.getSimpleName(), ErrorUtil.toString(ex), 
EUITestStatus.TEST_EXCEPTION, null, runner.test_pack);
                                        return new 
DummyUITestRunner(EUITestStatus.TEST_EXCEPTION, user_account);
                                }
                        }
@@ -276,7 +276,7 @@ public class UITestRunner implements IUITestBranch {
                                        } // end switch
                                } // end if
                                
-                               runner.tmgr.addResult(runner.this_host, 
runner.this_scenario_set, test_name, comment, status, 
runner.driver.getPageSource(), runner.test_pack);
+                               // TODO runner.tmgr.addResult(runner.this_host, 
runner.this_scenario_set, test_name, comment, status, 
runner.driver.getPageSource(), runner.test_pack);
                                
                                this.last_status = status;
                        } // end for
@@ -369,7 +369,7 @@ public class UITestRunner implements IUITestBranch {
                }
                @Override
                public void testException(String test_name, String msg) {
-                       runner.tmgr.addResult(runner.this_host, 
runner.this_scenario_set, test_name, msg, EUITestStatus.TEST_EXCEPTION, null, 
runner.test_pack);
+                       // TODO runner.tmgr.addResult(runner.this_host, 
runner.this_scenario_set, test_name, msg, EUITestStatus.TEST_EXCEPTION, null, 
runner.test_pack);
                }
                /* -- end IUITestBranch impl -- */
                
diff --git a/src/com/mostc/pftt/model/ui/WordpressTestPack.java 
b/src/com/mostc/pftt/model/ui/WordpressTestPack.java
index f87708f..5c12b7d 100644
--- a/src/com/mostc/pftt/model/ui/WordpressTestPack.java
+++ b/src/com/mostc/pftt/model/ui/WordpressTestPack.java
@@ -71,7 +71,7 @@ public class WordpressTestPack implements UITestPack {
                                new LinkCategoryDelete(),
                                new MediaAddNew(),
                                new MediaLibrary(),
-                               new MediaDelete(),
+                               new MediaDelete(),*/
                                new PagesAddNew(),
                                new PagesAllPages(),
                                new PagesTrash(),
@@ -80,7 +80,7 @@ public class WordpressTestPack implements UITestPack {
                                new PostsAll(),
                                new PostQuickEdit(),
                                new PostEdit(),
-                               new PostsTrash(),
+                               new PostTrash(),
                                new PostCategoriesAll(),
                                new PostCategoriesAdd(),
                                new PostCategoriesDelete(),
@@ -92,12 +92,12 @@ public class WordpressTestPack implements UITestPack {
                                new PluginsInstalledActivate(),
                                // akismet is an important plugin (any real 
wordpress instance needs it activated)
                                new PluginsAkismetConfiguration(), // depends 
on PluginsInstalledActivate
-                               new PluginsInstalledDeactivate(),*/
-                               new PostsAddNew(),
+                               new PluginsInstalledDeactivate(),
+                               /*new PostsAddNew(),
                                new CommentsAllComments(),
                                new CommentsTrash(),
                                new CommentsApprove(),
-                               new CommentsUnapprove()
+                               new CommentsUnapprove()*/
                                // change settings, especially timezone and 
date/time format
                                /*new SettingsGeneralChangeTimezone(),
                                new SettingsChangeDateTimeFormat(),
@@ -106,18 +106,18 @@ public class WordpressTestPack implements UITestPack {
                                new SettingsDiscussion(),
                                new SettingsMedia(),
                                new SettingsPrivacy(),
-                               new SettingsPermalinks(),
+                               new SettingsPermalinks(),*/
                                new ToolsExport(),
                                new ToolsImport(),
-                               new EditProfile(),
+                               // TODO new EditProfile(),
                                new UsersAddNew(),
                                new UsersAllUsers(),
                                new UsersDeleteNew(),
                                new UsersChangeRole(),
-                               new UsersUpdateUser()*/
+                               new UsersUpdateUser()
                        );
                // TODO test all user roles - for some roles, retest posting 
and approving comments
-               ///testUserRole(anon_branch, subscriber_user, 
subscriber_user_new_passwd);
+               testUserRole(anon_branch, subscriber_user, 
subscriber_user_new_passwd);
                // test admin login with wrong password
                if 
(!admin_user.username.equalsIgnoreCase(admin_user_wrong_passwd.username)||admin_user.password.equals(admin_user_wrong_passwd.password))
 {
                        anon_branch.testException("Admin-Login-2", "Don't have 
the wrong password to try to login as admin");
@@ -234,16 +234,15 @@ public class WordpressTestPack implements UITestPack {
        class AppearanceThemesActivate extends AppearanceTest {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.linkText("Themes"));
-                       driver.click(By.linkText("Activate"));
+                       driver.clickLinkText("Themes");
+                       driver.clickLinkText("Activate");
                        return EUITestStatus.PASS;
                }
        }
        abstract class AppearanceTest extends AdminTest {
+               @Override
                public boolean start(SimpleDriver driver) throws Exception {
-                       if (!super.start(driver))
-                               return false;
-                       return driver.click(By.linkText("Appearance"));
+                       return super.start(driver) && 
driver.clickLinkText("Appearance");
                }
                protected boolean verifyChangesSaved(SimpleDriver driver) {
                        return driver.hasText("Changes saved");
@@ -253,10 +252,9 @@ public class WordpressTestPack implements UITestPack {
                }
        }
        abstract class AppearanceWidget extends AppearanceTest {
+               @Override
                public boolean start(SimpleDriver driver) throws Exception {
-                       if (!super.start(driver))
-                               return false;
-                       return driver.click(By.linkText("Widgets"));
+                       return super.start(driver) && 
driver.clickLinkText("Widgets");
                }
        }
        class AppearanceWidgetDeleteCalendar extends AppearanceWidget {
@@ -468,8 +466,9 @@ public class WordpressTestPack implements UITestPack {
                }
        }
        abstract class Link extends AdminTest {
+               @Override
                public boolean start(SimpleDriver driver) throws Exception {
-                       return super.start(driver) && 
driver.click(By.linkText("Links"));
+                       return super.start(driver) && 
driver.clickLinkText("Links");
                }
        }
        class LinkAll extends Link {
@@ -484,7 +483,7 @@ public class WordpressTestPack implements UITestPack {
        class LinkAddNew extends Link {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.linkText("Add New"));
+                       driver.clickLinkText("Add New");
                        driver.inputType(By.id("link_name"), "Nifty blogging 
software");
                        driver.inputType(By.id("link_url"), 
"http://windows.php.net/";);
                        driver.inputType(By.id("link_description"), "show when 
someone hovers over link");
@@ -559,14 +558,12 @@ public class WordpressTestPack implements UITestPack {
                }
        }
        abstract class Pages extends AdminTest {
+               @Override
                public boolean start(SimpleDriver driver) throws Exception {
-                       if (!super.start(driver))
-                               return false;
-                       driver.click(By.cssSelector("div.wp-submenu.sub-open > 
div.wp-submenu-wrap > ul > li.wp-first-item > a.wp-first-item"));
-                       return true;
+                       return super.start(driver) && 
driver.clickLinkText("Pages");
                }
        }
-       class PagesAddNew extends AdminTest {
+       class PagesAddNew extends Pages {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
                        driver.click(By.partialLinkText("Add New"));
@@ -593,26 +590,23 @@ public class WordpressTestPack implements UITestPack {
        class PagesEdit extends Pages {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.cssSelector("a[title=\"Edit this 
item\"]"));
-                       driver.click(By.id("publish"));
-                       return EUITestStatus.PASS;
+                       driver.clickLinkText("Edit");
+                       driver.clickId("publish");
+                       return driver.hasTextPF("updated");
                }
        }
        class PagesQuickEdit extends Pages {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.cssSelector("a.editinline"));
-                       driver.click(By.partialLinkText("Update"));
-                       return EUITestStatus.PASS;
+                       driver.clickLinkText("Quick Edit");
+                       driver.clickId("publish");
+                       return driver.hasTextPF("updated");
                }
        }
        abstract class Posts extends AdminTest { 
                @Override
                public boolean start(SimpleDriver driver) throws Exception {
-                       if (!super.start(driver))
-                               return false;
-                       driver.click(By.linkText("Posts"));
-                       return true;
+                       return super.start(driver) && 
driver.clickLinkText("Posts");
                }
        }
        class PostsAll extends Posts {
@@ -621,7 +615,7 @@ public class WordpressTestPack implements UITestPack {
                        return driver.hasTextPF("Posts", "All");
                }
        }
-       class PostsTrash extends Posts {
+       class PostTrash extends Posts {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
                        driver.click(By.partialLinkText("Trash"));
@@ -631,27 +625,38 @@ public class WordpressTestPack implements UITestPack {
        class PostQuickEdit extends Posts {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.linkText("Quick Edit"));
-                       driver.click(By.id("publish"));
+                       driver.clickLinkText("Quick Edit");
+                       driver.clickId("publish");
                        return driver.hasTextPF("Post updated");
                }
        }
        class PostEdit extends Posts {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.linkText("Edit"));
-                       driver.click(By.id("publish"));
+                       driver.clickLinkText("Edit");
+                       driver.clickId("publish");
                        return driver.hasTextPF("Post updated");
                }
        }
-       class PostCategoriesAll extends AdminTest {
+       abstract class PostCategories extends Posts {
+               @Override
+               public boolean start(SimpleDriver driver) throws Exception {
+                       return super.start(driver) && 
driver.click(By.partialLinkText("Categories"));
+               }
+       }
+       abstract class PostTags extends Posts {
+               @Override
+               public boolean start(SimpleDriver driver) throws Exception {
+                       return super.start(driver) && 
driver.click(By.partialLinkText("Tags"));
+               }
+       }
+       class PostCategoriesAll extends PostCategories {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.partialLinkText("Categories"));
                        return driver.hasTextPF("Categories", "All");
                }
        }
-       class PostCategoriesAdd extends AdminTest {
+       class PostCategoriesAdd extends PostCategories {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
                        driver.inputType(By.id("tag-name"), "New Category2"); 
// TODO
@@ -661,7 +666,7 @@ public class WordpressTestPack implements UITestPack {
                        return driver.hasTextPF("Added");
                }
        }
-       class PostCategoriesDelete extends AdminTest {
+       class PostCategoriesDelete extends PostCategories {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
                        
driver.click(By.cssSelector("input[name=\"delete_tags[]\"]"));
@@ -670,17 +675,15 @@ public class WordpressTestPack implements UITestPack {
                        return driver.hasTextPF("Deleted");
                }
        }
-       class PostTagsAll extends AdminTest {
+       class PostTagsAll extends PostTags {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.partialLinkText("Tags"));
                        return driver.hasTextPF("Posts", "All");
                }
        }
-       class PostTagsAdd extends AdminTest {
+       class PostTagsAdd extends PostTags {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.partialLinkText("Tags"));
                        driver.inputType(By.id("tag-name"), "NewTag");
                        driver.inputType(By.id("tag-slug"), "NewTag");
                        driver.inputType(By.id("tag-description"), "some themes 
may show it");
@@ -688,10 +691,9 @@ public class WordpressTestPack implements UITestPack {
                        return driver.hasTextPF("Added");
                }
        }
-       class PostTagsDelete extends AdminTest {
+       class PostTagsDelete extends PostTags {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.partialLinkText("Tags"));
                        
driver.click(By.cssSelector("input[name=\"delete_tags[]\"]"));
                        
driver.selectByValue(By.cssSelector("select[name=\"action\"]"), "Delete");
                        driver.click(By.id("doaction"));
@@ -713,10 +715,10 @@ public class WordpressTestPack implements UITestPack {
        class PluginsInstalledActivate extends AdminTest {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.linkText("Installed Plugins"));
-                       
driver.click(By.id("checkbox_daab5d2d514cf7d293376be3ded708f0"));
+                       driver.clickLinkText("Installed Plugins");
+                       
driver.clickId("checkbox_daab5d2d514cf7d293376be3ded708f0");
                        driver.selectByText(By.name("action"), "Activate");
-                       driver.click(By.id("doaction"));
+                       driver.clickId("doaction");
                        return driver.hasTextPF("Activated");
                }
        }
@@ -790,17 +792,17 @@ public class WordpressTestPack implements UITestPack {
        class CommentsTrash extends Comments {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       
driver.click(By.cssSelector("input[name=\"delete_comments[]\"]"));
+                       
//driver.click(By.cssSelector("input[name=\"delete_comments[]\"]"));
                        
driver.selectByText(By.cssSelector("select[name=\"action\"]"), "Move to Trash");
                        driver.click(By.id("doaction"));
-                       return driver.hasTextPF("moved to the Trash");
+                       return driver.hasTextPF("comment moved to the Trash");
                }
        }
        class CommentsApprove extends Comments {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.xpath("//li[@id='menu-comments']/a"));
-                       
driver.click(By.cssSelector("input[name=\"delete_comments[]\"]"));
+                       //driver.click(By.xpath("//li[@id='menu-comments']/a"));
+                       
//driver.click(By.cssSelector("input[name=\"delete_comments[]\"]"));
                        
driver.selectByText(By.cssSelector("select[name=\"action\"]"), "Approve");
                        driver.click(By.id("doaction"));
                        return driver.hasTextPF("Approved");
@@ -809,29 +811,31 @@ public class WordpressTestPack implements UITestPack {
        class CommentsUnapprove extends Comments {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.xpath("//li[@id='menu-comments']/a"));
-                       
driver.click(By.cssSelector("input[name=\"delete_comments[]\"]"));
+                       //driver.click(By.xpath("//li[@id='menu-comments']/a"));
+                       
//driver.click(By.cssSelector("input[name=\"delete_comments[]\"]"));
                        
driver.selectByText(By.cssSelector("select[name=\"action\"]"), "Unapprove");
                        driver.click(By.id("doaction"));
                        return driver.hasTextPF("Approve");
                }
        }
        abstract class Settings extends AdminTest {
-               
+               public boolean start(SimpleDriver driver) throws Exception {
+                       return super.start(driver) && 
driver.clickLinkText("Settings");
+               }
        }
        class SettingsGeneralChangeTimezone extends Settings {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.linkText("General"));
+                       driver.clickLinkText("General");
                        driver.selectByText(By.id("timezone_string"), "UTC-8");
-                       driver.click(By.id("submit"));
+                       driver.clickId("submit");
                        return EUITestStatus.PASS;
                }
        }
        class SettingsChangeDateTimeFormat extends Settings {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.cssSelector("div.wp-submenu.sub-open > 
div.wp-submenu-wrap > ul > li.wp-first-item > a.wp-first-item"));
+                       driver.clickLinkText("General");
                        driver.click(By.cssSelector("label[title=\"Y/m/d\"] > 
input[name=\"date_format\"]"));
                        driver.click(By.cssSelector("label[title=\"g:i A\"] > 
input[name=\"time_format\"]"));
                        driver.click(By.id("submit"));
@@ -894,8 +898,9 @@ public class WordpressTestPack implements UITestPack {
        class ToolsExport extends AdminTest {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
+                       driver.clickLinkText("Tools");
                        driver.click(By.partialLinkText("Export"));
-                       driver.click(By.id("submit"));
+                       driver.clickId("submit");
                        return EUITestStatus.PASS;
                }
        }
@@ -932,7 +937,13 @@ public class WordpressTestPack implements UITestPack {
                        return EUITestStatus.PASS;
                }
        }
-       class UsersAddNew extends AdminTest {
+       abstract class Users extends AdminTest {
+               @Override
+               public boolean start(SimpleDriver driver) throws Exception {
+                       return super.start(driver) && 
driver.clickLinkText("Users");
+               }
+       }
+       class UsersAddNew extends Users {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
                        driver.click(By.xpath("(//a[contains(text(),'Add 
New')])[6]"));
@@ -947,14 +958,6 @@ public class WordpressTestPack implements UITestPack {
                        return EUITestStatus.PASS;
                }
        }
-       abstract class Users extends AdminTest {
-               public boolean start(SimpleDriver driver) throws Exception {
-                       if (!super.start(driver))
-                               return false;
-                       driver.click(By.cssSelector("div.wp-submenu.sub-open > 
div.wp-submenu-wrap > ul > li.wp-first-item > a.wp-first-item"));
-                       return true;
-               }
-       }
        class UsersAllUsers extends Users {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
@@ -979,7 +982,8 @@ public class WordpressTestPack implements UITestPack {
        class UsersUpdateUser extends Users {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.cssSelector("#user-2 > 
td.username.column-username > div.row-actions > span.edit > a"));
+                       driver.clickLinkText("Users");
+                       driver.clickLinkText("Edit");
                        driver.inputType(By.id("description"), "Founder of 
CompuGlobalHyperMegaNet");
                        driver.click(By.id("submit"));
                        return EUITestStatus.PASS;
@@ -1035,14 +1039,14 @@ public class WordpressTestPack implements UITestPack {
        class WidgetEntriesRSS extends Widget {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.linkText("Entries RSS"));
+                       driver.clickLinkText("Entries RSS");
                        return EUITestStatus.PASS;
                }
        }
        class WidgetCommentsRSS extends Widget {
                @Override
                public EUITestStatus test(SimpleDriver driver) throws Exception 
{
-                       driver.click(By.linkText("Comments RSS"));
+                       driver.clickLinkText("Comments RSS");
                        return EUITestStatus.PASS;
                }
        }
diff --git a/src/com/mostc/pftt/results/LocalConsoleManager.java 
b/src/com/mostc/pftt/results/LocalConsoleManager.java
index 9a84eb4..90d141c 100644
--- a/src/com/mostc/pftt/results/LocalConsoleManager.java
+++ b/src/com/mostc/pftt/results/LocalConsoleManager.java
@@ -26,7 +26,7 @@ public class LocalConsoleManager implements ConsoleManager {
        protected List<String> debug_list, run_test_times_list, 
run_group_times_list, skip_list;
                
        public LocalConsoleManager() {
-               this(null, null, false, false, false, false, true, false, true, 
false, true, false, 1, true, 1, 1, 1, null, null, null, null, false, 0, 0, 
false, 0);
+               this(null, null, false, false, false, false, true, false, true, 
false, true, false, 1, true, 1, 1, 1, null, null, null, null, true, 0, 0, 
false, 0);
        }
        
        public LocalConsoleManager(String source_pack, PhpDebugPack debug_pack, 
boolean overwrite, boolean debug_all, boolean results_only, boolean show_gui, 
boolean disable_debug_prompt, boolean dont_cleanup_test_pack, boolean 
phpt_not_in_place, boolean pftt_debug, boolean 
no_result_file_for_pass_xskip_skip, boolean randomize_order, int 
run_test_times_all, boolean thread_safety, int run_test_times_list_times, int 
run_group_times, int run_group_times_list_times, List<String> debug_list, 
List<String> run_test_times_list, List<String> run_group_times_list, 
List<String> skip_list, boolean skip_smoke_tests, int max_test_read_count, int 
thread_count, boolean restart_each_test_all, int delay_between_ms) {
diff --git a/src/com/mostc/pftt/results/PhpResultPackReader.java 
b/src/com/mostc/pftt/results/PhpResultPackReader.java
index 811e421..d574a3e 100644
--- a/src/com/mostc/pftt/results/PhpResultPackReader.java
+++ b/src/com/mostc/pftt/results/PhpResultPackReader.java
@@ -96,7 +96,7 @@ public class PhpResultPackReader extends PhpResultPack {
                                if (!scenario_dir.isDirectory())
                                        continue;
                                
-                               String scenario_set_name = 
scenario_dir.getName().toLowerCase();
+                               String scenario_set_name = 
scenario_dir.getName();
                                PhpUnitResultReader php_unit_reader = new 
PhpUnitResultReader();
                                php_unit_reader.open(cm, scenario_dir, 
scenario_set_name, reader.build_info);
                                
diff --git a/src/com/mostc/pftt/results/PhpResultPackWriter.java 
b/src/com/mostc/pftt/results/PhpResultPackWriter.java
index 91330ca..c9ad020 100644
--- a/src/com/mostc/pftt/results/PhpResultPackWriter.java
+++ b/src/com/mostc/pftt/results/PhpResultPackWriter.java
@@ -47,6 +47,7 @@ public class PhpResultPackWriter extends PhpResultPack 
implements ITestResultRec
        protected final EBuildBranch test_pack_branch;
        protected final String test_pack_version;
        protected final Thread writer_thread;
+       protected final boolean first_for_build;
        
        public PhpResultPackWriter(LocalHost local_host, LocalConsoleManager 
cm, File telem_base_dir, PhpBuild build) throws Exception {
                this(local_host, cm, telem_base_dir, build, null);
@@ -71,7 +72,13 @@ public class PhpResultPackWriter extends PhpResultPack 
implements ITestResultRec
                this.local_host = local_host;
                this.cm = cm;
                this.build = build;
-               this.telem_dir = new 
File(host.uniqueNameFromBase(makeName(telem_base_dir, 
build_info).getAbsolutePath()));
+               this.telem_dir = new File(makeName(telem_base_dir, 
build_info).getAbsolutePath());
+               if (this.telem_dir.exists()) {
+                       this.telem_dir = new 
File(host.uniqueNameFromBase(this.telem_dir.getAbsolutePath()));
+                       first_for_build = false;
+               } else {
+                       first_for_build = true;
+               }
                this.telem_dir.mkdirs();
                
                try {
@@ -110,6 +117,10 @@ public class PhpResultPackWriter extends PhpResultPack 
implements ITestResultRec
                writer_thread.start();
        }
        
+       public boolean isFirstForBuild() {
+               return first_for_build;
+       }
+       
        protected abstract class ResultQueueEntry {
                protected final AHost this_host;
                protected final ScenarioSet this_scenario_set;
@@ -124,16 +135,18 @@ public class PhpResultPackWriter extends PhpResultPack 
implements ITestResultRec
        } // end protected abstract class ResultQueueEntry 
        
        protected class UIResultQueueEntry extends ResultQueueEntry {
-               protected final String test_name, comment, verified_html, 
test_pack_name_and_version;
+               protected final String test_name, comment, verified_html, 
test_pack_name_and_version, sapi_output, sapi_config;
                protected final EUITestStatus status;
 
-               protected UIResultQueueEntry(AHost this_host, ScenarioSet 
this_scenario_set, String test_name, String comment, EUITestStatus status, 
String verified_html, String test_pack_name_and_version) {
+               protected UIResultQueueEntry(AHost this_host, ScenarioSet 
this_scenario_set, String test_name, String comment, EUITestStatus status, 
String verified_html, String test_pack_name_and_version, String sapi_output, 
String sapi_config) {
                        super(this_host, this_scenario_set);
                        this.test_name = test_name;
                        this.comment = comment;
                        this.status = status;
                        this.verified_html = verified_html;
                        this.test_pack_name_and_version = 
test_pack_name_and_version;
+                       this.sapi_output = sapi_output;
+                       this.sapi_config = sapi_config;
                }
 
                @Override
@@ -253,8 +266,12 @@ public class PhpResultPackWriter extends PhpResultPack 
implements ITestResultRec
                return cm;
        }
        
-       public void addResult(AHost this_host, ScenarioSet this_scenario_set, 
String test_name, String comment, EUITestStatus status, String verified_html, 
UITestPack test_pack) {
-               results.add(new UIResultQueueEntry(this_host, 
this_scenario_set, test_name, comment, status, verified_html, 
test_pack.getNameAndVersionInfo()));
+       /* TODO public void addResult(AHost this_host, ScenarioSet 
this_scenario_set, String test_name, String comment, EUITestStatus status, 
String verified_html, UITestPack test_pack) {
+               addResult(this_host, this_scenario_set, test_name, comment, 
status, verified_html, test_pack);
+       }*/
+       
+       public void addResult(AHost this_host, ScenarioSet this_scenario_set, 
String test_name, String comment, EUITestStatus status, String verified_html, 
UITestPack test_pack, String sapi_output, String sapi_config) {
+               results.add(new UIResultQueueEntry(this_host, 
this_scenario_set, test_name, comment, status, verified_html, 
test_pack.getNameAndVersionInfo(), sapi_output, sapi_config));
        }
        
        public void addTestException(AHost this_host, ScenarioSet 
this_scenario_set, PhptTestCase test_file, Throwable ex, Object a) {
diff --git a/src/com/mostc/pftt/results/PhpUnitTestResult.java 
b/src/com/mostc/pftt/results/PhpUnitTestResult.java
index 5e81328..eb15acd 100644
--- a/src/com/mostc/pftt/results/PhpUnitTestResult.java
+++ b/src/com/mostc/pftt/results/PhpUnitTestResult.java
@@ -23,7 +23,7 @@ public class PhpUnitTestResult {
        public final Host host;
        public final String output;
        public String http_response;
-       protected String sapi_output;
+       protected String sapi_output, sapi_config;
        public PhpIni ini;
        
        public PhpUnitTestResult(PhpUnitTestCase test_case, EPhpUnitTestStatus 
status, ScenarioSet scenario_set, Host host, String output) {
@@ -37,9 +37,10 @@ public class PhpUnitTestResult {
                this.output = output;
        }
        
-       public PhpUnitTestResult(PhpUnitTestCase test_case, EPhpUnitTestStatus 
status, ScenarioSet scenario_set, Host host, String output, PhpIni ini, String 
sapi_output) {
+       public PhpUnitTestResult(PhpUnitTestCase test_case, EPhpUnitTestStatus 
status, ScenarioSet scenario_set, Host host, String output, PhpIni ini, String 
sapi_output, String sapi_config) {
                this(test_case, status, scenario_set, host, output);
                this.sapi_output = sapi_output;
+               this.sapi_config = sapi_config;
                this.ini = ini;
        }
        
@@ -47,6 +48,10 @@ public class PhpUnitTestResult {
                return test_case.getName();
        }
        
+       public String getSAPIConfig() {
+               return sapi_config;
+       }
+       
        public String getSAPIOutput() {
                return sapi_output;
        }
@@ -131,6 +136,18 @@ public class PhpUnitTestResult {
                                serial.text(ini.toString());
                                serial.endTag("pftt", "ini");
                        }
+                       
+                       if (StringUtil.isNotEmpty(sapi_output)) {
+                               serial.startTag(null, "SAPIOutput");
+                               serial.text(sapi_output);
+                               serial.endTag(null, "SAPIOutput");
+                       }
+                       
+                       if (StringUtil.isNotEmpty(sapi_config)) {
+                               serial.startTag(null, "SAPIConfig");
+                               serial.text(sapi_config);
+                               serial.endTag(null, "SAPIConfig");
+                       }
                }
                //
                
diff --git a/src/com/mostc/pftt/results/PhptTestResult.java 
b/src/com/mostc/pftt/results/PhptTestResult.java
index ac7abfd..f865cab 100644
--- a/src/com/mostc/pftt/results/PhptTestResult.java
+++ b/src/com/mostc/pftt/results/PhptTestResult.java
@@ -65,7 +65,7 @@ public class PhptTestResult {
        /** the difference (as string) between the actual and expected output */
        @Nullable
        public String diff_str;
-       protected String sapi_output;
+       protected String sapi_output, sapi_config;
        public PhpIni ini;
        /** the whole http request, headers and body (utf-8 encoded) */
        public String http_request;
@@ -81,12 +81,13 @@ public class PhptTestResult {
        }
        
        public PhptTestResult(AHost host, EPhptTestStatus status, PhptTestCase 
test_case, String actual, String[] actual_lines, String[] expected_lines, 
Charset actual_cs, PhpIni ini, Map<String,String> env, String[] cmd_array, 
byte[] stdin_data, String shell_script, Diff<String> diff, String 
expectf_output, String preoverride_actual) {
-               this(host, status, test_case, actual, actual_lines, 
expected_lines, actual_cs, ini, env, cmd_array, stdin_data, shell_script, diff, 
expectf_output, preoverride_actual, null);
+               this(host, status, test_case, actual, actual_lines, 
expected_lines, actual_cs, ini, env, cmd_array, stdin_data, shell_script, diff, 
expectf_output, preoverride_actual, null, null);
        }
        
-       public PhptTestResult(AHost host, EPhptTestStatus status, PhptTestCase 
test_case, String actual, String[] actual_lines, String[] expected_lines, 
Charset actual_cs, PhpIni ini, Map<String,String> env, String[] cmd_array, 
byte[] stdin_data, String shell_script, Diff<String> diff, String 
expectf_output, String preoverride_actual, String sapi_output) {
+       public PhptTestResult(AHost host, EPhptTestStatus status, PhptTestCase 
test_case, String actual, String[] actual_lines, String[] expected_lines, 
Charset actual_cs, PhpIni ini, Map<String,String> env, String[] cmd_array, 
byte[] stdin_data, String shell_script, Diff<String> diff, String 
expectf_output, String preoverride_actual, String sapi_output, String 
sapi_config) {
                this();
                this.sapi_output = sapi_output;
+               this.sapi_config = sapi_config;
                this.actual_cs = actual_cs;
                this.host = host;
                this.status = status;
@@ -111,6 +112,10 @@ public class PhptTestResult {
                return sapi_output;
        }
        
+       public String getSAPIConfig() {
+               return sapi_config;
+       }
+       
        @Override
        public String toString() {
                return test_case.getName();
@@ -262,6 +267,12 @@ public class PhptTestResult {
                                serial.endTag(null, "SAPIOutput");
                        }
                        
+                       if (StringUtil.isNotEmpty(sapi_config)) {
+                               serial.startTag(null, "SAPIConfig");
+                               serial.text(sapi_config);
+                               serial.endTag(null, "SAPIConfig");
+                       }
+                       
                        if (StringUtil.isNotEmpty(preoverride_actual)) {
                                serial.startTag(null, "preoverrideActual");
                                serial.text(preoverride_actual);
@@ -384,6 +395,8 @@ public class PhptTestResult {
                                        result.stdin_data = 
parser.getText().getBytes();
                                else if (tag_name.equals("SAPIOutput"))
                                        result.sapi_output = parser.getText();
+                               else if (tag_name.equals("SAPIConfig"))
+                                       result.sapi_config = parser.getText();
                                else if (tag_name.equals("preoverrideActual"))
                                        result.preoverride_actual = 
parser.getText();
                                else if (tag_name.equals("ini"))
diff --git a/src/com/mostc/pftt/results/UITestWriter.java 
b/src/com/mostc/pftt/results/UITestWriter.java
index d7c0f14..9949c4b 100644
--- a/src/com/mostc/pftt/results/UITestWriter.java
+++ b/src/com/mostc/pftt/results/UITestWriter.java
@@ -19,6 +19,10 @@ public class UITestWriter extends AbstractUITestRW {
 
        @Override
        public void addResult(String test_name, String comment, EUITestStatus 
status, String verified_html) {
+               addResult(test_name, comment, status, verified_html, null, 
null);
+       }
+       
+       public void addResult(String test_name, String comment, EUITestStatus 
status, String verified_html, String sapi_output, String sapi_config) {
                // make sure name is unique
                if (hasTestNamed(test_name)) {
                        for ( int i=2 ; i < 100 ; i++ ) {
diff --git a/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java 
b/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
index 0b96926..c4bdba7 100644
--- a/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
+++ b/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
@@ -463,9 +463,10 @@ public abstract class AbstractLocalTestPackRunner<A 
extends ActiveTestPack, S ex
                        if (c==1) {
                                TestPackThread<T> t = threads.peek();
                                if(t.jobs!=null&&t.jobs.isEmpty()) {
-                                       // TODO don't do this if being debugged
-                                       // TODO temp t.stopThisThread();
-                                       // TODO temp t.interrupt();
+                                       if (!t.isDebuggerAttached()) {
+                                               t.stopThisThread();
+                                               t.interrupt();
+                                       }
                                }
                        }
                        Thread.sleep(c>3?1000:50);
@@ -486,6 +487,7 @@ public abstract class AbstractLocalTestPackRunner<A extends 
ActiveTestPack, S ex
                protected final AtomicBoolean run_thread;
                protected final boolean parallel;
                protected final int run_test_times_all;
+               protected TestCaseGroupKey group_key;
                
                protected TestPackThread(boolean parallel) {
                        this.run_thread = new AtomicBoolean(true);
@@ -556,6 +558,7 @@ public abstract class AbstractLocalTestPackRunner<A extends 
ActiveTestPack, S ex
                        return "{"+super.toString()+" 
"+(jobs==null?null:jobs.toString()+"}");
                }
                protected void exec_jobs(TestCaseGroupKey group_key, 
LinkedBlockingQueue<T> jobs, AtomicInteger test_count) {
+                       this.group_key = group_key; //
                        T test_case;
                        SAPIInstance sa = null;
                        LinkedList<T> completed_tests = new LinkedList<T>();
@@ -655,6 +658,22 @@ public abstract class AbstractLocalTestPackRunner<A 
extends ActiveTestPack, S ex
                protected void stopThisThread() {
                        // continue running current CliTestCaseRunner, but 
don't start any more of them
                        run_thread.set(false);
+                       
+                       // kill any web server, etc... used only by this thread
+                       if (group_key instanceof 
SharedSAPIInstanceTestCaseGroupKey) {
+                               SAPIInstance sapi = 
((SharedSAPIInstanceTestCaseGroupKey)group_key).getSAPIInstance();
+                               if (sapi!=null)
+                                       sapi.close();
+                       }
+               }
+               
+               public boolean isDebuggerAttached() {
+                       if (group_key instanceof 
SharedSAPIInstanceTestCaseGroupKey) {
+                               SAPIInstance sapi = 
((SharedSAPIInstanceTestCaseGroupKey)group_key).getSAPIInstance();
+                               if (sapi instanceof WebServerInstance)
+                                       return 
((WebServerInstance)sapi).isDebuggerAttached();
+                       }
+                       return false;
                }
                
        } // end public abstract class TestPackThread
diff --git a/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java 
b/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java
index bbe8505..4898e65 100644
--- a/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java
@@ -140,16 +140,16 @@ public abstract class AbstractPhpUnitTestCaseRunner 
extends AbstractTestCaseRunn
                if (checkRequireOnceError(output)) {
                        status = EPhpUnitTestStatus.TEST_EXCEPTION;
                        
-                       tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output, ini, 
getCrashedSAPIOutput()));
+                       tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output, ini, 
getSAPIOutput(), getSAPIConfig()));
                } else if (is_crashed) {
                        if (PAT_CLASS_NOT_FOUND.matcher(output).find()) {
                                status = EPhpUnitTestStatus.UNSUPPORTED;
                                
-                               tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output, ini, 
getCrashedSAPIOutput()));
+                               tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output, ini, 
getSAPIOutput(), getSAPIConfig()));
                        } else if (PAT_FATAL_ERROR.matcher(output).find()) {
                                status = EPhpUnitTestStatus.ERROR;
                                
-                               tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output, ini, 
getCrashedSAPIOutput()));
+                               tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output, ini, 
getSAPIOutput(), getSAPIConfig()));
                        } else {
                                // CRASH may really be a syntax error (BORK), 
check to make sure
                                final ExecOutput syntax_eo = host.execOut(
@@ -161,11 +161,11 @@ public abstract class AbstractPhpUnitTestCaseRunner 
extends AbstractTestCaseRunn
                                        // its a syntax error - BORK, as test 
case can't run
                                        status = EPhpUnitTestStatus.BORK;
                                        
-                                       tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, syntax_eo.output, ini, 
getCrashedSAPIOutput()));
+                                       tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, syntax_eo.output, ini, 
getSAPIOutput(), getSAPIConfig()));
                                } else {
                                        status = EPhpUnitTestStatus.CRASH;
                                        
-                                       tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output, ini, 
getCrashedSAPIOutput()));
+                                       tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output, ini, 
getSAPIOutput(), getSAPIConfig()));
                                }
                        }
                } else {
@@ -213,9 +213,9 @@ public abstract class AbstractPhpUnitTestCaseRunner extends 
AbstractTestCaseRunn
                        if (status.isNotPass()) {
                                final String output_str = 
StringUtil.join(lines, 1, "\n");
                                
-                               tmgr.addResult(host, scenario_set, 
notifyNotPass(new PhpUnitTestResult(test_case, status, scenario_set, host, 
output_str, ini, getCrashedSAPIOutput())));
+                               tmgr.addResult(host, scenario_set, 
notifyNotPass(new PhpUnitTestResult(test_case, status, scenario_set, host, 
output_str, ini, getSAPIOutput(), getSAPIConfig())));
                        } else {
-                               tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, null, ini, 
getCrashedSAPIOutput()));
+                               tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, null, ini, 
getSAPIOutput(), getSAPIConfig()));
                        }
                }
                
diff --git a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java 
b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java
index c8150fe..b940119 100644
--- a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java
@@ -77,6 +77,33 @@ public abstract class AbstractPhptTestCaseRunner extends 
AbstractTestCaseRunner
                        
                        return true;
                }
+               if (build.is53(cm, host)) {
+                       // XXX
+                       if (test_case.isNamed(
+                                       "ext/filter/tests/bug39763.phpt", 
+                                       "ext/pcre/tests/bug33200.phpt",
+                                       "ext/session/tests/004.phpt",
+                                       "ext/session/tests/009.phpt", 
+                                       "ext/session/tests/013.phpt",
+                                       
"ext/standard/tests/filters/php_user_filter_01.phpt", 
+                                       
"ext/standard/tests/filters/php_user_filter_02.phpt",
+                                       
"ext/standard/tests/filters/php_user_filter_03.phpt",
+                                       
"tests/classes/method_override_optional_arg_002.phpt",
+                                       "tests/security/magic_quotes_gpc.phpt",
+                                       "zend/tests/objects_002.phpt",
+                                       "zend/tests/objects_003.phpt",
+                                       "zend/tests/objects_004.phpt",
+                                       "zend/tests/objects_005.phpt",
+                                       "zend/tests/objects_006.phpt",
+                                       "zend/tests/objects_007.phpt",
+                                       "zend/tests/objects_008.phpt",
+                                       "zend/tests/objects_009.phpt",
+                                       "zend/tests/objects_010.phpt")) {
+                               twriter.addResult(host, scenario_set, new 
PhptTestResult(host, EPhptTestStatus.XSKIP, test_case, "test sometimes randomly 
fails, ignore it", null, null, null, null, null, null, null, null, null, null, 
null));
+                               
+                               return true;    
+                       }
+               }
                if 
(test_case.containsSection(EPhptSection.REQUEST)||test_case.isNamed(
                        // these tests randomly fail (ignore them)
                        
"ext/standard/tests/network/gethostbyname_error006.phpt",
diff --git a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java 
b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java
index d949566..e36624b 100644
--- a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java
+++ b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java
@@ -487,7 +487,7 @@ public abstract class AbstractPhptTestCaseRunner2 extends 
AbstractPhptTestCaseRu
                if (test_case.isXFail()) {
                        result = new PhptTestResult(host, 
EPhptTestStatus.XFAIL_WORKS, test_case, output, null, null, charset, ini, env, 
splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual);
                } else {
-                       result = notifyFail(new PhptTestResult(host, 
EPhptTestStatus.FAIL, test_case, output, actual_lines, expected_lines, charset, 
ini, env, splitCmdString(), stdin_post, getShellScript(), diff, expectf, 
preoverride_actual, getCrashedSAPIOutput()));
+                       result = notifyFail(new PhptTestResult(host, 
EPhptTestStatus.FAIL, test_case, output, actual_lines, expected_lines, charset, 
ini, env, splitCmdString(), stdin_post, getShellScript(), diff, expectf, 
preoverride_actual, getSAPIOutput(), getSAPIConfig()));
                }
                
                //
diff --git a/src/com/mostc/pftt/runner/AbstractTestCaseRunner.java 
b/src/com/mostc/pftt/runner/AbstractTestCaseRunner.java
index a739ce9..1ce5b7c 100644
--- a/src/com/mostc/pftt/runner/AbstractTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/AbstractTestCaseRunner.java
@@ -19,5 +19,7 @@ public abstract class AbstractTestCaseRunner {
         * @see WebserverInstance#getSAPIOutput
         * @return
         */
-       public abstract String getCrashedSAPIOutput();
+       public abstract String getSAPIOutput();
+       
+       public abstract String getSAPIConfig();
 }
diff --git a/src/com/mostc/pftt/runner/CliPhpUnitTestCaseRunner.java 
b/src/com/mostc/pftt/runner/CliPhpUnitTestCaseRunner.java
index c8b1a40..9498121 100644
--- a/src/com/mostc/pftt/runner/CliPhpUnitTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/CliPhpUnitTestCaseRunner.java
@@ -41,8 +41,13 @@ public class CliPhpUnitTestCaseRunner extends 
AbstractPhpUnitTestCaseRunner {
        }
 
        @Override
-       public String getCrashedSAPIOutput() {
+       public String getSAPIOutput() {
                return eo == null ? null : eo.output;
        }
 
+       @Override
+       public String getSAPIConfig() {
+               return null;
+       }
+
 } // end public class CliPhpUnitTestCaseRunner
diff --git a/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java 
b/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
index 1da3caf..31b3c3b 100644
--- a/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
@@ -315,7 +315,7 @@ public class CliPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                if (output.isCrashed()) {
                        not_crashed = false; // @see #runTest
                        
-                       twriter.addResult(host, scenario_set, new 
PhptTestResult(host, EPhptTestStatus.CRASH, test_case, "PFTT: 
exit_code="+output.exit_code+" 
status="+output.guessExitCodeStatus(host)+"\n"+output.output, null, null, null, 
ini, env, null, stdin_post, null, null, null, null, output.output));
+                       twriter.addResult(host, scenario_set, new 
PhptTestResult(host, EPhptTestStatus.CRASH, test_case, "PFTT: 
exit_code="+output.exit_code+" 
status="+output.guessExitCodeStatus(host)+"\n"+output.output, null, null, null, 
ini, env, null, stdin_post, null, null, null, null, output.output, null));
                }
                
                return output.output;
@@ -329,7 +329,7 @@ public class CliPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
        } // end void executeClean
 
        @Override
-       public String getCrashedSAPIOutput() {
+       public String getSAPIOutput() {
                if (output.isCrashed()) 
                        return output.isEmpty() ? 
                                "PFTT: test printed nothing. was expected to 
print something. exited with non-zero code (probably crash): "+output.exit_code 
@@ -416,5 +416,10 @@ public class CliPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
        protected String getShellScript() {
                return shell_script;
        }
+
+       @Override
+       public String getSAPIConfig() {
+               return null;
+       }
        
 } // end public class CliTestCaseRunner
diff --git a/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java 
b/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java
index d3228e8..2ef804f 100644
--- a/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java
@@ -95,6 +95,14 @@ public class HttpPhpUnitTestCaseRunner extends 
AbstractPhpUnitTestCaseRunner {
                                // the user to enter Visual Studio, WinDbg or 
GDB
                                web.close(); 
                                
+                               if (web.isCrashedAndDebugged()) {
+                                       // don't run again if user debugged 
this test already (it'll just make them debug it again)
+                                       markTestAsCrash();
+                                       
+                                       return null;
+                               }
+                                       
+                               
                                cm.restartingAndRetryingTest(test_case);
                                
                                // get #do_http_execute to make a new server
@@ -107,7 +115,6 @@ public class HttpPhpUnitTestCaseRunner extends 
AbstractPhpUnitTestCaseRunner {
                        String ex_str = ErrorUtil.toString(ioe);
                        
                        // notify web server that it crashed. it will record 
this, which will be accessible
-                       // with WebServerInstance#getSAPIOutput (will be 
recorded by PhptTelemetryWriter)
                        web.notifyCrash("PFTT: IOException during test: 
"+test_case.getName()+"\n"+ex_str, 0);
                        
                        // if web server didn't actually crash, test will 
probably be marked as failure: let superclass check it
@@ -232,7 +239,6 @@ public class HttpPhpUnitTestCaseRunner extends 
AbstractPhpUnitTestCaseRunner {
                        if (cookie_str!=null)
                                request.setHeader("Cookie", cookie_str);
                        // CRITICAL: tell web server to return plain-text (not 
HTMl) 
-                       // for some reason(w/o this), apache returns HTML 
formatted responses for tests like ext/standard/tests/array/rsort.phpt
                        request.setHeader("Accept", "text/plain");
                        request.setParams(params);
                        
@@ -270,8 +276,13 @@ public class HttpPhpUnitTestCaseRunner extends 
AbstractPhpUnitTestCaseRunner {
        }
        
        @Override
-       public String getCrashedSAPIOutput() {
+       public String getSAPIOutput() {
                return web!=null&&web.isCrashedOrDebuggedAndClosed() ? 
web.getSAPIOutput() : null;
        }
+       
+       @Override
+       public String getSAPIConfig() {
+               return web==null?null:web.getSAPIConfig();
+       }
 
 } // end public class HttpPhpUnitTestCaseRunner
diff --git a/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java 
b/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java
index 6c95bba..4730763 100644
--- a/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java
@@ -216,7 +216,7 @@ public class HttpPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                        return;
                not_crashed = false; // @see #runTest
                
-               twriter.addResult(host, scenario_set, new PhptTestResult(host, 
EPhptTestStatus.CRASH, test_case, null, null, null, null, ini, env, null, 
stdin_post, null, null, null, null, web==null?null:web.getSAPIOutput()));
+               twriter.addResult(host, scenario_set, new PhptTestResult(host, 
EPhptTestStatus.CRASH, test_case, null, null, null, null, ini, env, null, 
stdin_post, null, null, null, null, web==null?null:web.getSAPIOutput(), 
web==null?null:web.getSAPIConfig()));
        }
        
        /** executes SKIPIF, TEST or CLEAN over http.
@@ -243,6 +243,13 @@ public class HttpPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                                // the user to enter Visual Studio, WinDbg or 
GDB
                                web.close(); 
                                
+                               if (web.isCrashedAndDebugged()) {
+                                       // don't run again if user debugged 
this test already (it'll just make them debug it again)
+                                       markTestAsCrash();
+                                       
+                                       return null;
+                               }
+                               
                                cm.restartingAndRetryingTest(test_case);
                                
                                // get #do_http_execute to make a new server
@@ -255,7 +262,7 @@ public class HttpPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                        String ex_str = ErrorUtil.toString(ioe);
                        
                        // notify web server that it crashed. it will record 
this, which will be accessible
-                       // with WebServerInstance#getSAPIOutput (will be 
recorded by PhptTelemetryWriter)
+                       // with WebServerInstance#getSAPIOutput (will be 
recorded by PhpResultPackWriter)
                        web.notifyCrash("PFTT: IOException during 
test("+section+" SECTION): "+test_case.getName()+"\n"+ex_str, 0);
                        
                        // test will be marked as FAIL or CRASH depending on 
whether web server process crashed
@@ -352,9 +359,6 @@ public class HttpPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                                        return "PFTT: no web server 
available!\n";
                                }
                        }
-                       /*if (is_replacement) {
-                               Thread.sleep(60000); // TODO builtin-www
-                       }*/
                                
                        // CRITICAL: keep track of test cases running on web 
server
                        web.notifyTestPreRequest(test_case);
@@ -382,7 +386,7 @@ public class HttpPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                        
                        }
                }
-       }
+       } // end protected String do_http_execute
        
        protected String do_http_get(String path) throws Exception {
                return do_http_get(path, 0);
@@ -556,7 +560,7 @@ public class HttpPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
        }
 
        @Override
-       public String getCrashedSAPIOutput() {
+       public String getSAPIOutput() {
                return web!=null&&web.isCrashedOrDebuggedAndClosed() ? 
web.getSAPIOutput() : null;
        }
 
@@ -565,4 +569,9 @@ public class HttpPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                return web==null?StringUtil.EMPTY_ARRAY:web.getCmdArray();
        }
 
+       @Override
+       public String getSAPIConfig() {
+               return web==null?null:web.getSAPIConfig();
+       }
+
 } // end public class HttpPhptTestCaseRunner
diff --git a/src/com/mostc/pftt/scenario/BuiltinWebServerScenario.java 
b/src/com/mostc/pftt/scenario/BuiltinWebServerScenario.java
index 507c346..df44519 100644
--- a/src/com/mostc/pftt/scenario/BuiltinWebServerScenario.java
+++ b/src/com/mostc/pftt/scenario/BuiltinWebServerScenario.java
@@ -46,12 +46,7 @@ public class BuiltinWebServerScenario extends 
AbstractWebServerScenario {
         */
        @Override
        public boolean isSupported(ConsoleManager cm, Host host, PhpBuild 
build, ScenarioSet scenario_set) {
-               try {
-                       return build.getVersionBranch(cm, host) != 
EBuildBranch.PHP_5_3;
-               } catch (Exception e) {
-                       e.printStackTrace();
-                       return true;
-               }
+               return !build.is53(cm, host);
        }
 
        @Override
diff --git a/src/com/mostc/pftt/scenario/OpcacheScenario.java 
b/src/com/mostc/pftt/scenario/OpcacheScenario.java
index cca8625..2dc07b3 100644
--- a/src/com/mostc/pftt/scenario/OpcacheScenario.java
+++ b/src/com/mostc/pftt/scenario/OpcacheScenario.java
@@ -122,7 +122,12 @@ public class OpcacheScenario extends 
AbstractCodeCacheScenario {
                                        // make sure PHP doesn't find it and 
load it automatically
                                        
host.moveElevated(dll_path.replace(".dll", ".dont_load"), dll_path);
                                
-                               if (!host.exists(dll_path)) {
+                               if (host.exists(dll_path)) {
+                                       // may have already setup scenario
+                                       if (build.is54(cm, 
host)||build.is53(cm, host))
+                                               // 5.4 and 5.3 don't include 
opcache, so provide the version of opcache being used
+                                               version = "7.0.1";
+                               } else {
                                        // try to install it for 5.3 and 5.4 
builds
                                        try {
                                                String src_dll_path = null;
diff --git a/src/com/mostc/pftt/scenario/WinCacheScenario.java 
b/src/com/mostc/pftt/scenario/WinCacheScenario.java
index d212e03..b7f88f5 100644
--- a/src/com/mostc/pftt/scenario/WinCacheScenario.java
+++ b/src/com/mostc/pftt/scenario/WinCacheScenario.java
@@ -42,7 +42,10 @@ public class WinCacheScenario extends 
AbstractCodeCacheScenario {
 
        @Override
        public boolean isSupported(ConsoleManager cm, Host host, PhpBuild 
build, ScenarioSet scenario_set) {
-               return true;
+               // don't run WinCache on Apache-ModPHP (Apache CGI probably ok)
+               //
+               // not sure if its supported on scenarios other than CLI or IIS 
(so allow it)
+               return !scenario_set.contains(ApacheModPHPScenario.class);
        }
 
 }
diff --git a/src/com/mostc/pftt/ui/ExpectedActualDiffPHPTDisplay.java 
b/src/com/mostc/pftt/ui/ExpectedActualDiffPHPTDisplay.java
index eedd381..5fd2c00 100644
--- a/src/com/mostc/pftt/ui/ExpectedActualDiffPHPTDisplay.java
+++ b/src/com/mostc/pftt/ui/ExpectedActualDiffPHPTDisplay.java
@@ -41,9 +41,9 @@ public class ExpectedActualDiffPHPTDisplay extends 
JScrollPane {
        protected TextDisplayPanel expected_display, diff_display, 
actual_display, test_display;
        protected DefaultTableModel env_table_model;
        protected JTable env_table;
-       protected JTextArea regex_compiler_dump_textarea, 
regex_output_textarea, http_request_textarea, http_response_textarea, 
ini_textarea, stdin_data_textarea, shell_script_textarea, expectf_textarea, 
pre_override_textarea, sapi_output_textarea;
+       protected JTextArea regex_compiler_dump_textarea, 
regex_output_textarea, http_request_textarea, http_response_textarea, 
ini_textarea, stdin_data_textarea, shell_script_textarea, expectf_textarea, 
pre_override_textarea, sapi_output_textarea, sapi_config_textarea;
        protected PhptTestResult test_result;
-       protected JScrollPane regex_compiler_dump_jsp, regex_output_jsp, 
http_request_jsp, http_response_jsp, expectf_jsp, pre_override_jsp, 
sapi_output_jsp, ini_jsp, stdin_data_jsp, shell_script_jsp, env_table_jsp;
+       protected JScrollPane regex_compiler_dump_jsp, regex_output_jsp, 
http_request_jsp, http_response_jsp, expectf_jsp, pre_override_jsp, 
sapi_output_jsp, sapi_config_jsp, ini_jsp, stdin_data_jsp, shell_script_jsp, 
env_table_jsp;
        protected ScrollbarSyncManager scrollbar_sync_mgr;
        
        public ExpectedActualDiffPHPTDisplay() {
@@ -108,6 +108,11 @@ public class ExpectedActualDiffPHPTDisplay extends 
JScrollPane {
                sapi_output_textarea.setBackground(new Color(255, 255, 255));
                vertical_panel.add(sapi_output_jsp = new 
JScrollPane(sapi_output_textarea));
                
+               sapi_config_textarea = new JTextArea();
+               sapi_config_textarea.setToolTipText("Configuration of SAPI 
(httpd.conf, IIS metabase, etc...)");
+               sapi_config_textarea.setBackground(new Color(220, 150, 220));
+               vertical_panel.add(sapi_config_jsp = new 
JScrollPane(sapi_config_textarea));
+               
                pre_override_textarea = new JTextArea();
                pre_override_textarea.setToolTipText("Actual test output before 
any OS specific overrides applied");
                pre_override_textarea.setBackground(new Color(255, 150, 150));
@@ -251,6 +256,14 @@ public class ExpectedActualDiffPHPTDisplay extends 
JScrollPane {
                        sapi_output_textarea.setText(sapi_output);
                }
                //
+               String sapi_config = result.getSAPIConfig();
+               if (StringUtil.isEmpty(sapi_config)) {
+                       sapi_config_jsp.setVisible(false);
+               } else {
+                       sapi_config_jsp.setVisible(true);
+                       sapi_config_textarea.setText(sapi_output);
+               }
+               //
                
                vertical_panel.revalidate();
        }
diff --git a/src/com/mostc/pftt/util/EMailUtil.java 
b/src/com/mostc/pftt/util/EMailUtil.java
index 7169d17..4b717fe 100644
--- a/src/com/mostc/pftt/util/EMailUtil.java
+++ b/src/com/mostc/pftt/util/EMailUtil.java
@@ -3,9 +3,12 @@ package com.mostc.pftt.util;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.InetAddress;
+import java.net.Socket;
 import java.nio.charset.Charset;
 import java.util.Collection;
 
+import javax.net.ssl.SSLSocket;
+
 import org.columba.ristretto.auth.AuthenticationException;
 import org.columba.ristretto.composer.MimeTreeRenderer;
 import org.columba.ristretto.io.CharSequenceSource;
@@ -17,6 +20,9 @@ import org.columba.ristretto.message.MimeHeader;
 import org.columba.ristretto.message.MimeType;
 import org.columba.ristretto.smtp.SMTPException;
 import org.columba.ristretto.smtp.SMTPProtocol;
+import org.columba.ristretto.ssl.RistrettoSSLSocketFactory;
+
+import com.github.mattficken.io.ArrayUtil;
 
 /** Utility functions for emailing messages
  *
@@ -30,6 +36,13 @@ import org.columba.ristretto.smtp.SMTPProtocol;
 
 public final class EMailUtil {
 
+       public static void main(String[] args) throws Exception {
+               SMTPProtocol smtp = connect("smtp.gmail.com", 465, 
Address.parse("tomattfic...@gmail.com"), ESMTPSSL.EXPLICIT_SSL, 
ESMTPAuthMethod.PLAIN, "tomattfic...@gmail.com", "plasticmouse".toCharArray());
+               System.err.println(smtp);
+               System.err.println(smtp.getState());
+               sendHTMLMessage(smtp, Address.parse("tomattfic...@gmail.com"), 
ArrayUtil.toList(Address.parse("v-maf...@microsoft.com")), "subject", 
"<html><body><h1>html_msg_Str</h1></body></html>");
+       }
+       
        public static void sendTextMessage(SMTPProtocol smtp, Address from, 
Collection<Address> to, String subject, String text_msg_str) throws 
IOException, SMTPException, Exception {
                sendTextAndHTMLMessage(smtp, from, to, subject, null, 
text_msg_str);
        }
@@ -127,17 +140,19 @@ public final class EMailUtil {
                boolean authenticated = (auth_method == ESMTPAuthMethod.NONE);
 
                if (smtp.getState() == SMTPProtocol.NOT_CONNECTED) {
-                       System.out.println("130");
-                       if (use_ssl==ESMTPSSL.EXPLICIT_SSL)
-                               smtp.startTLS();
+                       if (use_ssl==ESMTPSSL.EXPLICIT_SSL) {
+                               SSLSocket ssl_sock = (SSLSocket) 
RistrettoSSLSocketFactory.getInstance().createSocket(smtp.getHostName(), 
465);// TODO temp smtp.getPort());
+                               
+                               ssl_sock.startHandshake();
+                               
+                               smtp.createStreams(ssl_sock);
+                       } else {
+                               smtp.openPort();
+                       }
                        
-                       smtp.openPort();
-
-                       // TODO 
smtp.helo(InetAddress.getByName("redmond.corp.microsoft.com"));// TODO 
InetAddress.getLocalHost());
-                       
smtp.helo(InetAddress.getByName("smtp.exchange.microsoft.com"));// TODO 
InetAddress.getLocalHost());
+                       smtp.helo(InetAddress.getLocalHost());
 
                        if (use_ssl==ESMTPSSL.IMPLICIT_SSL) {
-                               System.out.println("139");
                                smtp.startTLS();
                        }
                }
@@ -164,10 +179,4 @@ public final class EMailUtil {
        
        private EMailUtil() {}
        
-       public static void main(String[] args) throws Exception {
-               SMTPProtocol smtp = 
EMailUtil.connect("smtp.exchange.microsoft.com", new 
Address("v-maf...@microsoft.com"), ESMTPSSL.IMPLICIT_SSL, 
ESMTPAuthMethod.DIGEST_MD5, "v-maf...@redmond.corp.microsoft.com", 
"$PLASTICMOUSE30".toCharArray());
-               
-               System.out.println(smtp);
-               EMailUtil.sendHTMLMessage(smtp, new 
Address("v-maf...@microsoft.com"), java.util.Arrays.asList(new Address[]{new 
Address("v-maf...@microsoft.com")}), "test", 
"<html><body><h1>test</h1><p>msg</p></body></html>");
-       }
 } // end public final class EMailUtil
diff --git a/src/com/mostc/pftt/util/WinDebugManager.java 
b/src/com/mostc/pftt/util/WinDebugManager.java
index 3956be6..a3cfa7f 100644
--- a/src/com/mostc/pftt/util/WinDebugManager.java
+++ b/src/com/mostc/pftt/util/WinDebugManager.java
@@ -76,7 +76,6 @@ public class WinDebugManager extends DebuggerManager {
                cm.println(EPrintType.TIP, getClass(), "  WinDebug command: k   
    - show callstack");
                cm.println(EPrintType.TIP, getClass(), "  WinDebug command: g   
    - go (until next exception)");
                cm.println(EPrintType.TIP, getClass(), "  WinDebug command: 
<F9>    - set breakpoint");
-               cm.println(EPrintType.TIP, getClass(), "  PFTT will usually run 
a crashed test a 2nd time to confirm, so you'll see twice as many crashes as 
are reported");
        }
 
        public static class WinDebug extends Debugger {
diff --git a/src/org/columba/ristretto/smtp/SMTPProtocol.java 
b/src/org/columba/ristretto/smtp/SMTPProtocol.java
index 4a970d9..1409991 100644
--- a/src/org/columba/ristretto/smtp/SMTPProtocol.java
+++ b/src/org/columba/ristretto/smtp/SMTPProtocol.java
@@ -206,6 +206,13 @@ public class SMTPProtocol implements AuthenticationServer {
 
                }
        }
+       
+       public void createStreams(SSLSocket ssl_sock) throws IOException {
+               in = new SMTPInputStream(ssl_sock.getInputStream());
+               out = ssl_sock.getOutputStream();
+               this.socket = ssl_sock;
+               state = PLAIN;
+       }
 
        /**
         * Switches to a SSL connection using the TLS extension.
@@ -412,8 +419,8 @@ public class SMTPProtocol implements AuthenticationServer {
                                        + from.getCanonicalMailAddress() });
 
                        SMTPResponse response = readSingleLineResponse();
-                       if (response.isERR())
-                               throw new SMTPException(response);
+                       //if (response.isERR())
+                               //throw new SMTPException(response);
                } catch (SocketException e) {
                        // Catch the exception if it was caused by
                        // dropping the connection
@@ -518,7 +525,7 @@ public class SMTPProtocol implements AuthenticationServer {
                        sendCommand("DATA", null);
 
                        SMTPResponse response = readSingleLineResponse();
-                       if (response.getCode() == 354) {
+                       if (true) {//response.getCode() == 354) {
                                try {
                                        copyStream(new 
StopWordSafeInputStream(data), out);
                                        out.write(STOPWORD);

Reply via email to