Commit:    36873b54238ccf9aed2246724d8044835ce0c7ba
Author:    Matt Ficken <v-maf...@microsoft.com>         Thu, 14 Feb 2013 
00:00:14 -0800
Parents:   0d9f16578763e405db74efdb784e08873f93f07d
Branches:  master

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

Log:
adding ZendOptimizerPlus scenario


Former-commit-id: 9b3bb24569955394efeb0f797690490a6da981dd

Changed paths:
  M  conf/app/joomla.groovy
  M  src/com/mostc/pftt/host/RemotePhptTestPackRunner.java
  M  src/com/mostc/pftt/main/Config.java
  M  src/com/mostc/pftt/main/PfttMain.java
  M  src/com/mostc/pftt/model/app/PhpUnitSourceTestPack.java
  M  src/com/mostc/pftt/model/app/PhpUnitTemplate.groovy
  M  src/com/mostc/pftt/model/app/PhpUnitTestCase.java
  M  src/com/mostc/pftt/results/ITestResultReceiver.java
  M  src/com/mostc/pftt/results/PhpResultPackWriter.java
  M  src/com/mostc/pftt/results/PhpUnitResultWriter.java
  M  src/com/mostc/pftt/results/PhptResultWriter.java
  M  src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
  M  src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java
  M  src/com/mostc/pftt/runner/CliPhpUnitTestCaseRunner.java
  M  src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java
  M  src/com/mostc/pftt/runner/LocalPhpUnitTestPackRunner.java
  M  src/com/mostc/pftt/scenario/AbstractSAPIScenario.java
  M  src/com/mostc/pftt/scenario/AbstractWebServerScenario.java
  M  src/com/mostc/pftt/scenario/CLIScenario.java
  M  src/com/mostc/pftt/scenario/ZendOptimizerPlusScenario.java

diff --git a/conf/app/joomla.groovy b/conf/app/joomla.groovy
index 3edbef5..d2a277b 100644
--- a/conf/app/joomla.groovy
+++ b/conf/app/joomla.groovy
@@ -1,5 +1,3 @@
-import com.mostc.pftt.model.app.Symfony;
-
 
 def scenarios() {
        // install Joomla CMS
diff --git a/src/com/mostc/pftt/host/RemotePhptTestPackRunner.java 
b/src/com/mostc/pftt/host/RemotePhptTestPackRunner.java
index 2d9189d..4f579b8 100644
--- a/src/com/mostc/pftt/host/RemotePhptTestPackRunner.java
+++ b/src/com/mostc/pftt/host/RemotePhptTestPackRunner.java
@@ -62,7 +62,7 @@ public class RemotePhptTestPackRunner extends 
AbstractRemoteTestPackRunner<PhptA
                PhptSourceTestPack test_pack = new 
PhptSourceTestPack("C:\\php-sdk\\php-test-pack-5.5-nts-windows-vc9-x86-re6bde1f");
                test_pack.open(cm, host);
                
-               PhpResultPackWriter tmgr = new PhpResultPackWriter(host, cm, 
new File(host.getPhpSdkDir()), build, test_pack, scenario_set);
+               PhpResultPackWriter tmgr = new PhpResultPackWriter(host, cm, 
new File(host.getPhpSdkDir()), build, scenario_set);
                                
                RemotePhptTestPackRunner runner = new 
RemotePhptTestPackRunner(tmgr, scenario_set, build, host, host);
                if (args.length>0) {
diff --git a/src/com/mostc/pftt/main/Config.java 
b/src/com/mostc/pftt/main/Config.java
index b0df86c..f79b10c 100644
--- a/src/com/mostc/pftt/main/Config.java
+++ b/src/com/mostc/pftt/main/Config.java
@@ -25,6 +25,7 @@ import com.mostc.pftt.scenario.ScenarioSet;
 
 import groovy.lang.GroovyClassLoader;
 import groovy.lang.GroovyObject;
+import groovy.lang.MetaMethod;
 
 /** Handles loading a configuration (hosts, scenarios, credentials, etc...) 
from a groovy script.
  * 
@@ -140,11 +141,10 @@ public final class Config {
         * @return
         */
        public PhpUnitSourceTestPack getPhpUnitSourceTestPack(ConsoleManager 
cm) {
-               //this.get_php_unit_source_test_pack_method
                if (get_php_unit_source_test_pack_method==null)
                        return null;
                try {
-                       return (PhpUnitSourceTestPack) 
get_php_unit_source_test_pack_method.invokeMethod(CONFIGURE_FTP_CLIENT_METHOD, 
null);
+                       return (PhpUnitSourceTestPack) 
get_php_unit_source_test_pack_method.invokeMethod(GET_PHP_UNIT_SOURCE_TEST_PACK_METHOD,
 null);
                } catch ( Exception ex ) {
                        if (cm==null)
                                ex.printStackTrace(System.err);
@@ -327,7 +327,7 @@ public final class Config {
                        }
                }
                try {
-                       if (go.getProperty(CONFIGURE_SMTP_METHOD)!=null) {
+                       if (hasMethod(go, CONFIGURE_SMTP_METHOD)) {
                                if (config.configure_smtp_method!=null)
                                        
cm.println(EPrintType.OPERATION_FAILED_CONTINUING, "Config", 
CONFIGURE_SMTP_METHOD+"("+config.configure_smtp_file+") overriden by : 
"+file_name);
                                config.configure_smtp_method = go;
@@ -344,7 +344,7 @@ public final class Config {
                        }
                }
                try {
-                       if (go.getProperty(CONFIGURE_FTP_CLIENT_METHOD)!=null) {
+                       if (hasMethod(go, CONFIGURE_FTP_CLIENT_METHOD)) {
                                if (config.configure_ftp_client_method!=null)
                                        
cm.println(EPrintType.OPERATION_FAILED_CONTINUING, "Config", 
CONFIGURE_FTP_CLIENT_METHOD+"("+config.configure_ftp_client_file+") overriden 
by : "+file_name);
                                config.configure_ftp_client_method = go;
@@ -361,7 +361,7 @@ public final class Config {
                        }
                }
                try {
-                       if 
(go.getProperty(GET_PHP_UNIT_SOURCE_TEST_PACK_METHOD)!=null) {
+                       if (hasMethod(go, 
GET_PHP_UNIT_SOURCE_TEST_PACK_METHOD)) {
                                if 
(config.get_php_unit_source_test_pack_method!=null)
                                        
cm.println(EPrintType.OPERATION_FAILED_CONTINUING, "Config", 
GET_PHP_UNIT_SOURCE_TEST_PACK_METHOD+"("+config.get_php_unit_source_test_pack_file+")
 overriden by : "+file_name);
                                config.get_php_unit_source_test_pack_method = 
go;
@@ -379,4 +379,12 @@ public final class Config {
                }
        } // end protected static void loadObjectToConfig
        
+       protected static boolean hasMethod(GroovyObject go, String method_name) 
{
+               for ( MetaMethod mm : go.getMetaClass().getMethods() ) {
+                       if ( mm.getName().equals(method_name) )
+                               return true;
+               }
+               return false;
+       }
+       
 } // end public final class ConfigUtil
diff --git a/src/com/mostc/pftt/main/PfttMain.java 
b/src/com/mostc/pftt/main/PfttMain.java
index d732f42..49af013 100644
--- a/src/com/mostc/pftt/main/PfttMain.java
+++ b/src/com/mostc/pftt/main/PfttMain.java
@@ -149,7 +149,7 @@ public class PfttMain {
                        }
                        //
                        
-                       PhpResultPackWriter tmgr = new 
PhpResultPackWriter(host, cm, telem_dir(), build, test_pack, scenario_set);
+                       PhpResultPackWriter tmgr = new 
PhpResultPackWriter(host, cm, telem_dir(), build, scenario_set);
                        LocalPhptTestPackRunner test_pack_runner = new 
LocalPhptTestPackRunner(tmgr.getConsoleManager(), tmgr, scenario_set, build, 
storage_host, host);
                        cm.showGUI(test_pack_runner);
                        
@@ -219,7 +219,7 @@ public class PfttMain {
                        
                        LinkedList<PhptTestCase> test_cases = new 
LinkedList<PhptTestCase>();
                        
-                       PhpResultPackWriter tmgr = new 
PhpResultPackWriter(host, cm, telem_dir(), build, test_pack, scenario_set);
+                       PhpResultPackWriter tmgr = new 
PhpResultPackWriter(host, cm, telem_dir(), build, scenario_set);
                        test_pack.cleanup(cm);
                        cm.println(EPrintType.IN_PROGRESS, 
"PhptSourceTestPack", "enumerating test cases from test-pack...");
                        test_pack.read(test_cases, names, 
tmgr.getConsoleManager(), tmgr, build, true); // TODO true?
@@ -646,7 +646,7 @@ public class PfttMain {
                                        //  2. search current dir / assume 
filename is absolute path
                                        //  3. search $PFTT_DIR/conf
                                        //  4. search $PFTT_DIR/conf/internal
-                                       //  5. search $PFTT_DIR/conf/apps
+                                       //  5. search $PFTT_DIR/conf/app
                                        File config_file = new File(part);
                                        if (config_file.exists()) {
                                                if 
(!config_files.contains(config_file))
@@ -677,12 +677,12 @@ public class PfttMain {
                                                                                
        if (!config_files.contains(config_file))
                                                                                
                config_files.add(config_file);
                                                                                
} else {
-                                                                               
        config_file = new File(LocalHost.getLocalPfttDir()+"/conf/apps/"+part);
+                                                                               
        config_file = new File(LocalHost.getLocalPfttDir()+"/conf/app/"+part);
                                                                                
        if (config_file.exists()) {
                                                                                
                if (!config_files.contains(config_file))
                                                                                
                        config_files.add(config_file);
                                                                                
        } else {
-                                                                               
                config_file = new 
File(LocalHost.getLocalPfttDir()+"/conf/apps/"+part+".groovy");
+                                                                               
                config_file = new 
File(LocalHost.getLocalPfttDir()+"/conf/app/"+part+".groovy");
                                                                                
                if (config_file.exists()) {
                                                                                
                        if (!config_files.contains(config_file))
                                                                                
                                config_files.add(config_file);
@@ -782,43 +782,32 @@ public class PfttMain {
                LocalConsoleManager cm = new LocalConsoleManager(source_pack, 
debug_pack, force, debug, results_only, show_gui, disable_debug_prompt, 
dont_cleanup_test_pack, phpt_not_in_place, pftt_debug, 
no_result_file_for_pass_xskip_skip, randomize_order, run_test_times_all, 
                                thread_safety, run_test_times_list_times, 
run_group_times_all, run_group_times_list_times, debug_list, 
run_test_times_list, run_group_times_list, skip_list);
                
-               //
-               /*
-               SSHHost remote_host = new SSHHost("192.168.1.117", 
"administrator", "password01!");
-               System.out.println(remote_host.isWindows());
-               SMBDeduplicationScenario d = new 
SMBDeduplicationScenario(remote_host, "F:");
-               //SMBDFSScenario d = new SMBDFSScenario(remote_host);
-               SMBStorageDir dir = d.createStorageDir(cm, rt.host);
-               System.out.println(dir.getLocalPath(rt.host));
-               System.out.println(dir.notifyTestPackInstalled(cm, rt.host));
-               */
+               if (config_files.size()>0) {
+                       config = Config.loadConfigFromFiles(cm, 
(File[])config_files.toArray(new File[config_files.size()]));
+                       System.out.println("PFTT: Config: loaded 
"+config_files);
+               } else {
+                       File default_config_file = new 
File(rt.host.getPfttDir()+"/conf/default.groovy");
+                       config = Config.loadConfigFromFiles(cm, 
default_config_file);
+                       System.out.println("PFTT: Config: no config files 
loaded... using defaults only ("+default_config_file+")");
+               }
                
-               /*{
-                       ScenarioSet scenario_set = 
ScenarioSet.getDefaultScenarioSets().get(0);
+               // TODO
+               {
+                       ScenarioSet scenario_set = 
config.getScenarioSets().get(0);
                        PhpBuild build = new 
PhpBuild("c:/php-sdk/php-5.5-ts-windows-vc9-x86-re6bde1f");
                        build.open(cm, rt.host);
                        
-                       PhpUnitSourceTestPack test_pack = new 
PhpUnitSourceTestPack();
-                       
-                       //new Symfony().setup(test_pack);
-                       new JoomlaPlatform().setup(test_pack);
+                       PhpUnitSourceTestPack test_pack = 
config.getPhpUnitSourceTestPack(cm);
+                       test_pack.open(cm, rt.host); // CRITICAL
                        
-                       LocalPhpUnitTestPackRunner r = new 
LocalPhpUnitTestPackRunner(cm, null, scenario_set, build, rt.host);
+                       PhpResultPackWriter tmgr = new 
PhpResultPackWriter(rt.host, cm, new File(rt.host.getPhpSdkDir()), build, 
scenario_set);
+                       LocalPhpUnitTestPackRunner r = new 
LocalPhpUnitTestPackRunner(cm, tmgr, scenario_set, build, rt.host, rt.host);
                        r.runAllTests(test_pack);
+                       
+                       tmgr.close();
                } //
                
                System.exit(0);
-               */
-               //
-               
-               if (config_files.size()>0) {
-                       config = Config.loadConfigFromFiles(cm, 
(File[])config_files.toArray(new File[config_files.size()]));
-                       System.out.println("PFTT: Config: loaded 
"+config_files);
-               } else {
-                       File default_config_file = new 
File(rt.host.getPfttDir()+"/conf/default.groovy");
-                       config = Config.loadConfigFromFiles(cm, 
default_config_file);
-                       System.out.println("PFTT: Config: no config files 
loaded... using defaults only ("+default_config_file+")");
-               }
 
                //
                // help user find/install WinDebug properly
diff --git a/src/com/mostc/pftt/model/app/PhpUnitSourceTestPack.java 
b/src/com/mostc/pftt/model/app/PhpUnitSourceTestPack.java
index d20c1b6..c433246 100644
--- a/src/com/mostc/pftt/model/app/PhpUnitSourceTestPack.java
+++ b/src/com/mostc/pftt/model/app/PhpUnitSourceTestPack.java
@@ -197,7 +197,7 @@ public abstract class PhpUnitSourceTestPack implements 
SourceTestPack<PhpUnitAct
                        } else if (file.getName().endsWith("Test.php")) {
                                String file_name = 
Host.pathFrom(php_unit_dist.path.getAbsolutePath(), file.getAbsolutePath());
                                
-                               String test_name = 
PhpUnitTestCase.normalizeName(file_name);
+                               String test_name = 
PhpUnitTestCase.normalizeFileName(file_name);
                                
                                if (blacklist_test_names.contains(test_name))
                                        continue;
diff --git a/src/com/mostc/pftt/model/app/PhpUnitTemplate.groovy 
b/src/com/mostc/pftt/model/app/PhpUnitTemplate.groovy
index b61da62..c2abe37 100644
--- a/src/com/mostc/pftt/model/app/PhpUnitTemplate.groovy
+++ b/src/com/mostc/pftt/model/app/PhpUnitTemplate.groovy
@@ -30,11 +30,11 @@ public class PhpUnitTemplate {
         * @param env - environment variables
         * @return
         */
-       public static String renderTemplate(AHost host, PhpUnitTestCase 
test_case, String preamble_code, String bootstrap_file, String cwd, String 
include_path, String[] included_files, Map<String, String> globals, Map<String, 
String> constants, HashMap<String, String> env) {
-               return renderTemplate(host, test_case, preamble_code, 
bootstrap_file, cwd, include_path, included_files, globals, constants, env, 
false);
+       public static String renderTemplate(AHost host, PhpUnitTestCase 
test_case, String preamble_code, String bootstrap_file, String cwd, String 
include_path, String[] included_files, Map<String, String> globals, Map<String, 
String> constants, HashMap<String, String> env, String my_temp_dir) {
+               return renderTemplate(host, test_case, preamble_code, 
bootstrap_file, cwd, include_path, included_files, globals, constants, env, 
my_temp_dir, false);
        }
        
-       public static String renderTemplate(AHost host, PhpUnitTestCase 
test_case, String preamble_code, String bootstrap_file, String cwd, String 
include_path, String[] included_files, Map<String, String> globals, Map<String, 
String> constants, HashMap<String, String> env, boolean strict) {
+       public static String renderTemplate(AHost host, PhpUnitTestCase 
test_case, String preamble_code, String bootstrap_file, String cwd, String 
include_path, String[] included_files, Map<String, String> globals, Map<String, 
String> constants, HashMap<String, String> env, String my_temp_dir, boolean 
strict) {
                // XXX will need to get these values from PHP code 
                // data source: PhpUnit_Framework_TestCase constructor (default 
value)
                String data = "a:0:{}";
@@ -46,15 +46,25 @@ public class PhpUnitTemplate {
                StringWriter sw = new StringWriter(16384);
                PrintWriter pw = new PrintWriter(sw);
                
+               my_temp_dir = StringUtil.cslashes(host.fixPath(my_temp_dir));
+               
                // PFTT mod: need to set date.timezone=UTC... for some reason,
                //           ini file doesn't work, date_default_timezone_set() 
and ini_set() must both
                //           be used to suppress related errors symfony phpunit 
tests
+               //           
+               //           also set ENV vars in PHP for the temproary dir... 
for CLI or Apache, sometimes setting the
+               //           temporary dir ENV vars passed to AHost#exec 
doesn't always work
+               //           @see PHP sys_get_temp_dir() - many Symfony 
filesystem tests use this
                pw.print(
 """<?php
 set_include_path('$include_path');
 date_default_timezone_set('UTC');
 ini_set('date.timezone', 'UTC');
 require 'PHPUnit/Autoload.php';
+putenv('TMP=$my_temp_dir');
+putenv('TEMP=$my_temp_dir');
+putenv('TMPDIR=$my_temp_dir');
+
 """)
                if (StringUtil.isNotEmpty(bootstrap_file)) {
                        pw.print("""require_once '$bootstrap_file';
diff --git a/src/com/mostc/pftt/model/app/PhpUnitTestCase.java 
b/src/com/mostc/pftt/model/app/PhpUnitTestCase.java
index eaf57e8..0419102 100644
--- a/src/com/mostc/pftt/model/app/PhpUnitTestCase.java
+++ b/src/com/mostc/pftt/model/app/PhpUnitTestCase.java
@@ -21,7 +21,11 @@ public class PhpUnitTestCase extends TestCase {
        
        protected PhpUnitTestCase(PhpUnitDist php_unit_dist, String filename, 
String className, String methodName) {
                this.php_unit_dist = php_unit_dist;
+               // don't need to call #normalizeFilename here usually. it's 
called in PhpUnitSourcetestPack#readDir...
+               // calling it (again )here would be a performance hit
                this.filename = filename;
+               // don't need to normalize classname:
+               // if it has \ thats ok b/c its legal PHP (namespaces) whereas 
it won't be / b/c that's illegal in PHP
                this.className = className;
                this.methodName = methodName;
        }
@@ -36,7 +40,7 @@ public class PhpUnitTestCase extends TestCase {
                return getName();
        }
 
-       public static String normalizeName(String test_name) {
+       public static String normalizeFileName(String test_name) {
                return Host.toUnixPath(test_name).toLowerCase();
        }
 
diff --git a/src/com/mostc/pftt/results/ITestResultReceiver.java 
b/src/com/mostc/pftt/results/ITestResultReceiver.java
index 4319fb8..58637c7 100644
--- a/src/com/mostc/pftt/results/ITestResultReceiver.java
+++ b/src/com/mostc/pftt/results/ITestResultReceiver.java
@@ -6,11 +6,9 @@ import com.mostc.pftt.scenario.ScenarioSet;
 
 public interface ITestResultReceiver {
        public void addResult(AHost this_host, ScenarioSet this_scenario_set, 
PhptTestResult result);
+       public void addResult(AHost host, ScenarioSet scenario_set, 
PhpUnitTestResult result);
 
        public void addTestException(AHost this_host, ScenarioSet 
this_scenario_set, TestCase test_file, Throwable ex, Object a);
        public void addTestException(AHost this_host, ScenarioSet 
this_scenario_set, TestCase test_case, Throwable ex, Object a, Object b);
-       public void setTotalCount(int size);
-
-       public void addResult(AHost host, ScenarioSet scenario_set,
-                       PhpUnitTestResult phpUnitTestResult);
+       public void setTotalCount(int size);    
 }
diff --git a/src/com/mostc/pftt/results/PhpResultPackWriter.java 
b/src/com/mostc/pftt/results/PhpResultPackWriter.java
index 0630370..2f1a671 100644
--- a/src/com/mostc/pftt/results/PhpResultPackWriter.java
+++ b/src/com/mostc/pftt/results/PhpResultPackWriter.java
@@ -17,7 +17,6 @@ import com.mostc.pftt.model.core.ECPUArch;
 import com.mostc.pftt.model.core.ECompiler;
 import com.mostc.pftt.model.core.EPhptTestStatus;
 import com.mostc.pftt.model.core.PhpBuild;
-import com.mostc.pftt.model.core.PhptSourceTestPack;
 import com.mostc.pftt.model.core.PhptTestCase;
 import com.mostc.pftt.scenario.ScenarioSet;
 import com.mostc.pftt.util.ErrorUtil;
@@ -41,7 +40,6 @@ public class PhpResultPackWriter extends PhpResultPack 
implements ITestResultRec
        protected PrintWriter global_exception_writer;
        protected LocalConsoleManager cm;
        protected PhpBuild build;
-       protected PhptSourceTestPack test_pack;
        protected LinkedBlockingQueue<ResultQueueEntry> results;
        protected boolean run = true;
        
@@ -77,7 +75,7 @@ public class PhpResultPackWriter extends PhpResultPack 
implements ITestResultRec
                return new File(base.getAbsolutePath() + sb);
        }
        
-       public PhpResultPackWriter(LocalHost local_host, LocalConsoleManager 
cm, File telem_base_dir, PhpBuild build, PhptSourceTestPack test_pack, 
ScenarioSet scenario_set) throws Exception {
+       public PhpResultPackWriter(LocalHost local_host, LocalConsoleManager 
cm, File telem_base_dir, PhpBuild build, ScenarioSet scenario_set) throws 
Exception {
                super(local_host);
                
                phpt_writer_map = new 
HashMap<AHost,HashMap<ScenarioSet,PhptResultWriter>>(16);
@@ -93,7 +91,6 @@ public class PhpResultPackWriter extends PhpResultPack 
implements ITestResultRec
                this.local_host = local_host;
                this.cm = cm;
                this.build = build;
-               this.test_pack = test_pack;
                this.telem_dir = new File(host.uniqueNameFromBase(makeName(cm, 
host, telem_base_dir, build, scenario_set).getAbsolutePath()));
                this.telem_dir.mkdirs();
                
@@ -160,6 +157,7 @@ public class PhpResultPackWriter extends PhpResultPack 
implements ITestResultRec
                        w.handleResult(cm, this_host, this_scenario_set, 
this_result);
                        
                        // show on console
+                       // TODO
                        System.out.println(this_result.status+" 
"+this_result.test_case);
                        
                        if (cm!=null) {
@@ -196,6 +194,10 @@ public class PhpResultPackWriter extends PhpResultPack 
implements ITestResultRec
                        }
                        
                        w.writeResult(this_result);
+                       
+                       // show on console
+                       // TODO
+                       System.out.println(this_result.status+" 
"+this_result.test_case);
                }
                
        } // end protected class PhpUnitResultQueueEntry
diff --git a/src/com/mostc/pftt/results/PhpUnitResultWriter.java 
b/src/com/mostc/pftt/results/PhpUnitResultWriter.java
index 619a909..e3736ba 100644
--- a/src/com/mostc/pftt/results/PhpUnitResultWriter.java
+++ b/src/com/mostc/pftt/results/PhpUnitResultWriter.java
@@ -4,13 +4,19 @@ import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
 
 import javax.annotation.concurrent.NotThreadSafe;
 
 import org.kxml2.io.KXmlSerializer;
 
+import com.mostc.pftt.model.app.EPhpUnitTestStatus;
 import com.mostc.pftt.util.PFTTVersionUtil;
 
 /** Writes PhpUnitTestResults from a single test run with a single scenario 
set on a single host with a single build.
@@ -31,12 +37,15 @@ import com.mostc.pftt.util.PFTTVersionUtil;
 @NotThreadSafe
 public class PhpUnitResultWriter {
        protected final KXmlSerializer serial;
+       protected final File dir;
        protected final OutputStream out;
+       protected final HashMap<EPhpUnitTestStatus,StatusListEntry> 
status_list_map;
        private boolean is_first_result = true;
        private String last_test_suite_name;
        private int test_count, percent_total, pass, failure, error, warning, 
notice, skip, deprecated, not_implemented, unsupported, test_exception, crash, 
bork, xskip;
        
        public PhpUnitResultWriter(File dir) throws FileNotFoundException, 
IOException {
+               this.dir = dir;
                dir.mkdirs();
                
                // TODO include hosts or scenario-set in file name because that 
will make it easier to view a bunch of them in Notepad++ or other MDIs
@@ -49,15 +58,61 @@ public class PhpUnitResultWriter {
                
                // setup serializer to indent XML (pretty print) so its easy 
for people to read
                
serial.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output";, 
true);
+               
+               status_list_map = new 
HashMap<EPhpUnitTestStatus,StatusListEntry>();
+               for ( EPhpUnitTestStatus status : EPhpUnitTestStatus.values() ) 
{
+                       status_list_map.put(status, new 
StatusListEntry(status));
+               }
        }
+       
+       protected class StatusListEntry {
+               protected final EPhpUnitTestStatus status;
+               protected final File journal_file;
+               protected final PrintWriter journal_writer;
+               protected final LinkedList<String> test_names;
+               
+               public StatusListEntry(EPhpUnitTestStatus status) throws 
IOException {
+                       this.status = status;
+                       
+                       journal_file = new File(dir+"/"+status+".journal.txt");
+                       journal_writer = new PrintWriter(new 
FileWriter(journal_file));
+                       test_names = new LinkedList<String>();
+               }
+               
+               public void write(PhpUnitTestResult result) {
+                       final String test_name = result.test_case.getName();
+                       
+                       journal_writer.println(test_name);
+                       
+                       test_names.add(test_name);
+               }
+               public void close() throws IOException {
+                       journal_writer.close();
+                       
+                       // sort alphabetically
+                       Collections.sort(test_names);
+                       
+                       PrintWriter pw = new PrintWriter(new FileWriter(new 
File(dir+"/"+status+".txt")));
+                       for ( String test_name : test_names )
+                               pw.println(test_name);
+                       pw.close();
+                       
+                       // if here, collecting the results and writing them in 
sorted-order has worked ... 
+                       //   don't need journal anymore (pftt didn't crash, 
fail, etc...)
+                       journal_file.delete();
+               }
+       } // end protected class StatusListEntry
 
        // @see PHPUnit/Util/Log/JUnit.php#startTestSuite
        public void writeResult(PhpUnitTestResult result) throws 
IllegalArgumentException, IllegalStateException, IOException {
+               status_list_map.get(result.status).write(result);
+               
+               
                // write file header
                String test_suite_name = null; // TODO 
result.test_case.php_unit_dist.getName();
                if (is_first_result) {
                        serial.startDocument("utf-8",  null);
-                       serial.setPrefix("pftt", 
PFTTVersionUtil.PFTT_PROJECT_URL);
+                       serial.setPrefix("pftt", "pftt");
                        serial.startTag(null, "testsuites");
                        if (test_suite_name==null)
                                writeTestSuiteStart(test_suite_name);
@@ -124,7 +179,7 @@ public class PhpUnitResultWriter {
        
        private void writeTestSuiteStart(String test_suite_name) throws 
IllegalArgumentException, IllegalStateException, IOException {
                serial.startTag(null, "testsuite");
-               serial.attribute(null, "name", test_suite_name);
+               // TODO serial.attribute(null, "name", test_suite_name);
        }
        
        private void writeTestSuiteEnd() throws IllegalArgumentException, 
IllegalStateException, IOException {
@@ -139,6 +194,10 @@ public class PhpUnitResultWriter {
                
                serial.flush();
                out.close();
+               
+               // do this after finishing phpunit.xml since that's more 
important than alphabetizing text file lists
+               for ( StatusListEntry e : status_list_map.values() )
+                       e.close();
        }
        
        private void writeTally() throws IllegalArgumentException, 
IllegalStateException, IOException {
@@ -147,13 +206,13 @@ public class PhpUnitResultWriter {
                serial.attribute(null, "test_count", 
Integer.toString(test_count));
                serial.attribute(null, "percent_total", 
Integer.toString(percent_total));
                serial.attribute(null, "pass", Integer.toString(pass));
-               serial.attribute(null, "pass_percent", 
Float.toString(pass/percent_total));
+               serial.attribute(null, "pass_percent", Float.toString( 100.0f * 
(((float)pass)/((float)percent_total))));
                serial.attribute(null, "failure", Integer.toString(failure));
-               serial.attribute(null, "failure_percent", 
Float.toString(failure/percent_total));
+               serial.attribute(null, "failure_percent", Float.toString( 
100.0f * (((float)failure)/((float)percent_total))));
                serial.attribute(null, "error", Integer.toString(error));
-               serial.attribute(null, "error_percent", 
Float.toString(error/percent_total));
+               serial.attribute(null, "error_percent", Float.toString( 100.0f 
* (((float)error)/((float)percent_total))));
                serial.attribute(null, "crash", Integer.toString(crash));
-               serial.attribute(null, "crash_percent", 
Float.toString(crash/percent_total));
+               serial.attribute(null, "crash_percent", Float.toString( 100.0f 
* (((float)crash)/((float)percent_total))));
                serial.attribute(null, "skip", Integer.toString(skip));
                serial.attribute(null, "xskip", Integer.toString(xskip));
                serial.attribute(null, "warning", Integer.toString(warning));
diff --git a/src/com/mostc/pftt/results/PhptResultWriter.java 
b/src/com/mostc/pftt/results/PhptResultWriter.java
index 539a4c8..2ee6828 100644
--- a/src/com/mostc/pftt/results/PhptResultWriter.java
+++ b/src/com/mostc/pftt/results/PhptResultWriter.java
@@ -7,7 +7,9 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintWriter;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.LinkedList;
 
 import org.kxml2.io.KXmlSerializer;
 
@@ -19,24 +21,52 @@ import com.mostc.pftt.results.ConsoleManager.EPrintType;
 import com.mostc.pftt.scenario.ScenarioSet;
 
 public class PhptResultWriter {
-       final File dir;
-       final HashMap<EPhptTestStatus,PrintWriter> status_list_map;
-       final KXmlSerializer serial;
+       protected final File dir;
+       protected final HashMap<EPhptTestStatus,StatusListEntry> 
status_list_map;
+       protected final KXmlSerializer serial;
        
-       PhptResultWriter(File dir) throws IOException {
+       public PhptResultWriter(File dir) throws IOException {
                this.dir = dir;
                
                dir.mkdirs();
                
-               status_list_map = new HashMap<EPhptTestStatus,PrintWriter>();
+               status_list_map = new 
HashMap<EPhptTestStatus,StatusListEntry>();
                serial  = new KXmlSerializer();
                // setup serializer to indent XML (pretty print) so its easy 
for people to read
                
serial.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output";, 
true);
                
-               for(EPhptTestStatus status:EPhptTestStatus.values()) {
-                       File file = new File(dir+"/"+status+".txt");
-                       PrintWriter pw = new PrintWriter(new FileWriter(file));
+               for(EPhptTestStatus status:EPhptTestStatus.values())
+                       status_list_map.put(status, new 
StatusListEntry(status));
+       }
+       
+       protected class StatusListEntry {
+               protected final EPhptTestStatus status;
+               protected final File journal_file;
+               protected final PrintWriter journal_writer;
+               protected final LinkedList<String> test_names;
+               
+               public StatusListEntry(EPhptTestStatus status) throws 
IOException {
+                       this.status = status;
+                       
+                       journal_file = new File(dir+"/"+status+".journal.txt");
+                       journal_writer = new PrintWriter(new 
FileWriter(journal_file));
+                       test_names = new LinkedList<String>();
+               }
+               
+               public void write(PhptTestResult result) {
+                       final String test_name = result.test_case.getName();
+                       
+                       journal_writer.println(test_name);
+                       
+                       test_names.add(test_name);
+               }
+               public void close() throws IOException {
+                       journal_writer.close();
+                       
+                       // sort alphabetically
+                       Collections.sort(test_names);
                        
+                       PrintWriter pw = new PrintWriter(new FileWriter(new 
File(dir+"/"+status+".txt")));
                        switch(status) {
                        case XSKIP:
                        case UNSUPPORTED:
@@ -49,16 +79,17 @@ public class PhptResultWriter {
                        default:
                                break;
                        } // end switch
+                       for ( String test_name : test_names )
+                               pw.println(test_name);
+                       pw.close();
                        
-                       status_list_map.put(status, pw);
+                       // if here, collecting the results and writing them in 
sorted-order has worked ... 
+                       //   don't need journal anymore (pftt didn't crash, 
fail, etc...)
+                       journal_file.delete();
                }
-       }
+       } // end protected class StatusListEntry
 
-       public void close() {
-               for ( PrintWriter pw : status_list_map.values() ) {
-                       pw.close();
-               }
-               
+       public void close() throws IOException {
                // write tally file with 
                try {
                        /*PhptTallyFile tally = new PhptTallyFile();
@@ -85,16 +116,13 @@ public class PhptResultWriter {
                } catch ( Exception ex ) {
                        ex.printStackTrace();
                }
+               
+               for ( StatusListEntry e : status_list_map.values() )
+                       e.close();
        } // end public void close
        
        protected void handleResult(ConsoleManager cm, AHost host, ScenarioSet 
scenario_set, PhptTestResult result) {
-               
-               try {
-                       PrintWriter pw = status_list_map.get(result.status);
-                       pw.println(result.test_case.getName());
-               } catch (Exception ex) {
-                       ex.printStackTrace();
-               }
+               status_list_map.get(result.status).write(result);
        
                
                final String test_case_base_name = 
result.test_case.getBaseName();
diff --git a/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java 
b/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
index a87f260..42410ac 100644
--- a/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
+++ b/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java
@@ -191,7 +191,9 @@ public abstract class AbstractLocalTestPackRunner<A extends 
ActiveTestPack, S ex
                        System.out.println((run_time/1000)+" seconds"); // TODO 
console manager
                        
                        // if not -dont-cleanup-test-pack and if successful, 
delete test-pack (otherwise leave it behind for user to analyze the internal 
exception(s))
-                       if (!cm.isDontCleanupTestPack() && 
+                       if (!cm.isDontCleanupTestPack() &&
+                                       this.active_test_pack != null && // 
TODO phpunit?
+                                       
this.active_test_pack.getStorageDirectory() != null && // TODO does phpunit 
need this?
                                        
!this.active_test_pack.getStorageDirectory().equals(
                                                        
src_test_pack.getSourceDirectory())) {
                                cm.println(EPrintType.IN_PROGRESS, getClass(), 
"deleting/cleaning-up active test-pack: "+this.active_test_pack);
@@ -497,7 +499,10 @@ public abstract class AbstractLocalTestPackRunner<A 
extends ActiveTestPack, S ex
                                                        sa = 
((SharedSAPIInstanceTestCaseGroupKey)group_key).getSAPIInstance();
                                                        if 
(sa==null||sa.isCrashed()||(debugger_attached && 
!((WebServerInstance)sa).isDebuggerAttached())) {
                                                                
//((SharedSAPIInstanceTestCaseGroupKey)group_key).setSAPIInstance(
-                                                               sa = 
((AbstractWebServerScenario)sapi_scenario).smgr.getWebServerInstance(cm, 
runner_host, build, group_key.getPhpIni(), group_key.getEnv(), 
active_test_pack.getStorageDirectory(), (WebServerInstance) sa, 
debugger_attached, completed_tests);
+                                                               sa = 
((AbstractWebServerScenario)sapi_scenario).smgr.getWebServerInstance(cm, 
runner_host, build, group_key.getPhpIni(), group_key.getEnv(), 
+                                                                               
active_test_pack==null?null: // TODO phpunit
+                                                                               
+                                                                               
active_test_pack.getStorageDirectory(), (WebServerInstance) sa, 
debugger_attached, completed_tests);
                                                                //);
                                                                
                                                                // TODO don't 
store sa on group_key! (don't share sa between threads)
diff --git a/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java 
b/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java
index 2e37efd..3966671 100644
--- a/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java
@@ -14,6 +14,8 @@ import com.mostc.pftt.model.app.PhpUnitTemplate;
 import com.mostc.pftt.model.app.PhpUnitTestCase;
 import com.mostc.pftt.model.core.PhpBuild;
 import com.mostc.pftt.results.ConsoleManager;
+import com.mostc.pftt.results.ITestResultReceiver;
+import com.mostc.pftt.results.PhpUnitTestResult;
 import com.mostc.pftt.scenario.ScenarioSet;
 
 /** runs a single PhpUnitTestCase
@@ -22,11 +24,22 @@ import com.mostc.pftt.scenario.ScenarioSet;
  *
  */
 
+// having PFTT directly run PhpUnit test cases itself, instead of just 
wrapping `phpunit` allows for:
+//   -faster execution (threads)
+//   -Web Server support ('cut closer to actual server')
+//      -more accurate results
+//      -usually only a slight or no difference
+//      -but if you care about accurate, quality or thorough testing
+//      -or if care about how well your software actually works
+//   -counting additional statuses (ex: xskip)
+//   -accurate crash detection
+//
 public abstract class AbstractPhpUnitTestCaseRunner extends 
AbstractTestCaseRunner {
        public static final String DB_DSN = "DB_DSN";
        public static final String DB_USER = "DB_USER";
        public static final String DB_PASSWD = "DB_PASSWD";
        public static final String DB_DBNAME = "DB_DBNAME";
+       protected final ITestResultReceiver tmgr;
        protected final Map<String, String> globals;
        protected final Map<String, String> env;
        protected final Map<String,String> constants;
@@ -40,7 +53,8 @@ public abstract class AbstractPhpUnitTestCaseRunner extends 
AbstractTestCaseRunn
        protected final String my_temp_dir;
        protected boolean is_crashed;
 
-       public AbstractPhpUnitTestCaseRunner(Map<String, String> globals, 
Map<String, String> env, ConsoleManager cm, AHost host, ScenarioSet 
scenario_set, PhpBuild build, PhpUnitTestCase test_case, String my_temp_dir, 
Map<String,String> constants, String include_path, String[] include_files) {
+       public AbstractPhpUnitTestCaseRunner(ITestResultReceiver tmgr, 
Map<String, String> globals, Map<String, String> env, ConsoleManager cm, AHost 
host, ScenarioSet scenario_set, PhpBuild build, PhpUnitTestCase test_case, 
String my_temp_dir, Map<String,String> constants, String include_path, String[] 
include_files) {
+               this.tmgr = tmgr;
                this.globals = globals;
                this.env = env;
                this.cm = cm;
@@ -66,9 +80,13 @@ public abstract class AbstractPhpUnitTestCaseRunner extends 
AbstractTestCaseRunn
                
                // BN: some phpunit tests (symfony) seem to not cleanup files 
or directories they create, sometimes
                // have a temporary directory used to run each test and 
forcibly clean it between each test run to avoid this problem
-               // set both TMP and TEMP!!!!
+               // set both TMP and TEMP and TMPDIR!!!!
                env.put("TEMP", my_temp_dir);
                env.put("TMP", my_temp_dir);
+               env.put("TMPDIR", my_temp_dir);
+               // these ENV vars are also set again in PHP code @see 
phpUnitTemplate to make sure that they're used
+               // @see PHP sys_get_temp_dir() - many Symfony filesystem tests 
use this
+               
                
                
                //////// prepared, generate PHP code
@@ -83,7 +101,8 @@ public abstract class AbstractPhpUnitTestCaseRunner extends 
AbstractTestCaseRunn
                                include_files,
                                globals,
                                constants,
-                               env
+                               env,
+                               my_temp_dir
                        );
        }
        
@@ -110,11 +129,11 @@ public abstract class AbstractPhpUnitTestCaseRunner 
extends AbstractTestCaseRunn
                        if (PAT_CLASS_NOT_FOUND.matcher(output).find()) {
                                status = EPhpUnitTestStatus.UNSUPPORTED;
                                
-                               System.out.println(status+" "+test_case);
+                               tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output));
                        } else if (PAT_FATAL_ERROR.matcher(output).find()) {
                                status = EPhpUnitTestStatus.ERROR;
                                
-                               System.out.println(status+" "+test_case);
+                               tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output));
                        } else {
                                // CRASH may really be a syntax error (BORK), 
check to make sure
                                final ExecOutput syntax_eo = 
host.execOut(build.getPhpExe()+" -l "+template_file, Host.ONE_MINUTE, 
test_case.php_unit_dist.path.getAbsolutePath());
@@ -122,13 +141,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));
-                                       System.out.println(status+" 
"+test_case);
+                                       tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, syntax_eo.output));
                                } else {
                                        status = EPhpUnitTestStatus.CRASH;
                                        
-                                       //tmgr.addResult(host, scenario_set, 
new PhpUnitTestResult(test_case, status, scenario_set, host, eo.output));
-                                       System.out.println(status+" 
"+test_case);
+                                       tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output));
                                }
                        }
                } else {
@@ -166,11 +183,9 @@ public abstract class AbstractPhpUnitTestCaseRunner 
extends AbstractTestCaseRunn
                        if (status.isNotPass()) {
                                final String output_str = 
StringUtil.join(lines, 1, "\n");
                                
-                               //tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output_str));
-                               System.out.println(status+" "+test_case);
+                               tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, output_str));
                        } else {
-                               //tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, null));
-                               System.out.println(status+" "+test_case);
+                               tmgr.addResult(host, scenario_set, new 
PhpUnitTestResult(test_case, status, scenario_set, host, null));
                        }
                }
                
diff --git a/src/com/mostc/pftt/runner/CliPhpUnitTestCaseRunner.java 
b/src/com/mostc/pftt/runner/CliPhpUnitTestCaseRunner.java
index 8b6f2c6..b92d29c 100644
--- a/src/com/mostc/pftt/runner/CliPhpUnitTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/CliPhpUnitTestCaseRunner.java
@@ -9,13 +9,14 @@ import com.mostc.pftt.host.Host;
 import com.mostc.pftt.model.app.PhpUnitTestCase;
 import com.mostc.pftt.model.core.PhpBuild;
 import com.mostc.pftt.results.ConsoleManager;
+import com.mostc.pftt.results.ITestResultReceiver;
 import com.mostc.pftt.scenario.ScenarioSet;
 
 public class CliPhpUnitTestCaseRunner extends AbstractPhpUnitTestCaseRunner {
        protected ExecOutput eo;
 
-       public CliPhpUnitTestCaseRunner(Map<String, String> globals, 
Map<String, String> env, ConsoleManager cm, AHost host, ScenarioSet 
scenario_set, PhpBuild build, PhpUnitTestCase test_case, String my_temp_dir, 
Map<String, String> constants, String include_path, String[] include_files) {
-               super(globals, env, cm, host, scenario_set, build, test_case, 
my_temp_dir, constants, include_path, include_files);
+       public CliPhpUnitTestCaseRunner(ITestResultReceiver tmgr, Map<String, 
String> globals, Map<String, String> env, ConsoleManager cm, AHost host, 
ScenarioSet scenario_set, PhpBuild build, PhpUnitTestCase test_case, String 
my_temp_dir, Map<String, String> constants, String include_path, String[] 
include_files) {
+               super(tmgr, globals, env, cm, host, scenario_set, build, 
test_case, my_temp_dir, constants, include_path, include_files);
        }
        
        @Override
diff --git a/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java 
b/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java
index 2a1c897..6e1c0e8 100644
--- a/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java
@@ -25,6 +25,7 @@ import com.mostc.pftt.model.sapi.WebServerInstance;
 import com.mostc.pftt.model.sapi.WebServerManager;
 import com.mostc.pftt.model.smoke.RequiredExtensionsSmokeTest;
 import com.mostc.pftt.results.ConsoleManager;
+import com.mostc.pftt.results.ITestResultReceiver;
 import com.mostc.pftt.scenario.ScenarioSet;
 import com.mostc.pftt.util.ErrorUtil;
 
@@ -40,11 +41,11 @@ public class HttpPhpUnitTestCaseRunner extends 
AbstractPhpUnitTestCaseRunner {
        protected final HttpRequestExecutor httpexecutor;
        protected final PhpIni ini;
 
-       public HttpPhpUnitTestCaseRunner(
+       public HttpPhpUnitTestCaseRunner(ITestResultReceiver tmgr,
                        HttpParams params, HttpProcessor httpproc, 
HttpRequestExecutor httpexecutor, WebServerManager smgr, WebServerInstance web,
                        Map<String, String> globals, Map<String, String> env, 
ConsoleManager cm, AHost host, ScenarioSet scenario_set, PhpBuild build,
                        PhpUnitTestCase test_case, String my_temp_dir, 
Map<String, String> constants, String include_path, String[] include_files) {
-               super(globals, env, cm, host, scenario_set, build, test_case, 
my_temp_dir, constants, include_path, include_files);
+               super(tmgr, globals, env, cm, host, scenario_set, build, 
test_case, my_temp_dir, constants, include_path, include_files);
                this.params = params;
                this.httpproc = httpproc;
                this.httpexecutor = httpexecutor;
diff --git a/src/com/mostc/pftt/runner/LocalPhpUnitTestPackRunner.java 
b/src/com/mostc/pftt/runner/LocalPhpUnitTestPackRunner.java
index 1fb82ec..c8d59b2 100644
--- a/src/com/mostc/pftt/runner/LocalPhpUnitTestPackRunner.java
+++ b/src/com/mostc/pftt/runner/LocalPhpUnitTestPackRunner.java
@@ -25,6 +25,7 @@ import com.mostc.pftt.model.app.PhpUnitSourceTestPack;
 import com.mostc.pftt.model.app.PhpUnitTestCase;
 import com.mostc.pftt.model.core.PhpBuild;
 import com.mostc.pftt.model.sapi.ApacheManager;
+import com.mostc.pftt.model.sapi.SharedSAPIInstanceTestCaseGroupKey;
 import com.mostc.pftt.model.sapi.TestCaseGroupKey;
 import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.ITestResultReceiver;
@@ -73,12 +74,12 @@ public class LocalPhpUnitTestPackRunner extends 
AbstractLocalTestPackRunner<PhpU
 
        @Override
        protected void setupStorageAndTestPack(ITestPackStorageDir storage_dir, 
List<PhpUnitTestCase> test_cases) {
-               
+               // TODO
        }
        
        @Override
        protected TestCaseGroupKey createGroupKey(PhpUnitTestCase test_case, 
TestCaseGroupKey group_key) throws Exception {
-               return new TestCaseGroupKey(null, null);
+               return group_key == null ? new 
SharedSAPIInstanceTestCaseGroupKey(null, null) : group_key;
        }
 
        @Override
@@ -101,8 +102,7 @@ public class LocalPhpUnitTestPackRunner extends 
AbstractLocalTestPackRunner<PhpU
 
                @Override
                protected void runTest(TestCaseGroupKey group_key, 
PhpUnitTestCase test_case) throws IOException, Exception, Throwable {
-                       HttpPhpUnitTestCaseRunner r = new 
HttpPhpUnitTestCaseRunner(params, httpproc, httpexecutor, smgr, null, globals, 
env, cm, runner_host, scenario_set, build, test_case, my_temp_dir, constants, 
test_case.php_unit_dist.getIncludePath(), 
test_case.php_unit_dist.getIncludeFiles());
-                       //CliPhpUnitTestCaseRunner r = new 
CliPhpUnitTestCaseRunner(globals, env, cm, rt.host, scenario_set, build, 
test_case, temp_dir, constants, test_case.php_unit_dist.getIncludePath(), 
test_case.php_unit_dist.getIncludeFiles());
+                       AbstractPhpUnitTestCaseRunner r = 
sapi_scenario.createPhpUnitTestCaseRunner(cm, twriter, globals, env, 
runner_host, scenario_set, build, test_case, my_temp_dir, constants, 
test_case.php_unit_dist.getIncludePath(), 
test_case.php_unit_dist.getIncludeFiles());
                        r.runTest();
                }
                
diff --git a/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java 
b/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java
index 82a9a4a..b6e040a 100644
--- a/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java
+++ b/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java
@@ -1,6 +1,9 @@
 package com.mostc.pftt.scenario;
 
+import java.util.Map;
+
 import com.mostc.pftt.host.AHost;
+import com.mostc.pftt.model.app.PhpUnitTestCase;
 import com.mostc.pftt.model.core.ESAPIType;
 import com.mostc.pftt.model.core.PhpBuild;
 import com.mostc.pftt.model.core.PhpIni;
@@ -10,6 +13,7 @@ import com.mostc.pftt.model.core.PhptTestCase;
 import com.mostc.pftt.model.sapi.TestCaseGroupKey;
 import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.ITestResultReceiver;
+import com.mostc.pftt.runner.AbstractPhpUnitTestCaseRunner;
 import com.mostc.pftt.runner.AbstractPhptTestCaseRunner;
 import com.mostc.pftt.runner.LocalPhptTestPackRunner.PhptThread;
 
@@ -86,5 +90,7 @@ public abstract class AbstractSAPIScenario extends 
AbstractSerialScenario {
        public abstract TestCaseGroupKey createTestGroupKey(ConsoleManager cm, 
AHost host, PhpBuild build, ScenarioSet scenario_set, PhptActiveTestPack 
active_test_pack, PhptTestCase test_case, TestCaseGroupKey group_key) throws 
Exception;
        
        public abstract PhpIni createIniForTest(ConsoleManager cm, AHost host, 
PhpBuild build, PhptActiveTestPack active_test_pack, ScenarioSet scenario_set);
+
+       public abstract AbstractPhpUnitTestCaseRunner 
createPhpUnitTestCaseRunner(ConsoleManager cm, ITestResultReceiver twriter, 
Map<String,String> globals, Map<String,String> env, AHost runner_host, 
ScenarioSet scenario_set, PhpBuild build, PhpUnitTestCase test_case, String 
my_temp_dir, Map<String,String> constants, String include_path, String[] 
include_files);
        
 } // end public abstract class AbstractSAPIScenario
diff --git a/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java 
b/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java
index ad99aa4..ca2f51e 100644
--- a/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java
+++ b/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java
@@ -19,6 +19,7 @@ import org.apache.http.protocol.RequestUserAgent;
 import com.mostc.pftt.host.AHost;
 import com.mostc.pftt.host.Host;
 import com.mostc.pftt.host.HostGroup;
+import com.mostc.pftt.model.app.PhpUnitTestCase;
 import com.mostc.pftt.model.core.EPhptSection;
 import com.mostc.pftt.model.core.ESAPIType;
 import com.mostc.pftt.model.core.PhpBuild;
@@ -33,7 +34,9 @@ import com.mostc.pftt.model.sapi.WebServerManager;
 import com.mostc.pftt.model.smoke.RequiredExtensionsSmokeTest;
 import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.ITestResultReceiver;
+import com.mostc.pftt.runner.AbstractPhpUnitTestCaseRunner;
 import com.mostc.pftt.runner.AbstractPhptTestCaseRunner;
+import com.mostc.pftt.runner.HttpPhpUnitTestCaseRunner;
 import com.mostc.pftt.runner.HttpPhptTestCaseRunner;
 import com.mostc.pftt.runner.LocalPhptTestPackRunner.PhptThread;
 
@@ -169,4 +172,8 @@ public abstract class AbstractWebServerScenario extends 
AbstractSAPIScenario {
                return HttpPhptTestCaseRunner.willSkip(cm, twriter, host, 
scenario_set, type, build, test_case);
        }
        
+       public AbstractPhpUnitTestCaseRunner 
createPhpUnitTestCaseRunner(ConsoleManager cm, ITestResultReceiver twriter, 
Map<String,String> globals, Map<String,String> env, AHost runner_host, 
ScenarioSet scenario_set, PhpBuild build, PhpUnitTestCase test_case, String 
my_temp_dir, Map<String,String> constants, String include_path, String[] 
include_files) {
+               return new HttpPhpUnitTestCaseRunner(twriter, params, httpproc, 
httpexecutor, smgr, null, globals, env, cm, runner_host, scenario_set, build, 
test_case, my_temp_dir, constants, include_path, include_files);
+       }
+       
 } // end public abstract class AbstractWebServerScenario
diff --git a/src/com/mostc/pftt/scenario/CLIScenario.java 
b/src/com/mostc/pftt/scenario/CLIScenario.java
index f964dd2..c9926c9 100644
--- a/src/com/mostc/pftt/scenario/CLIScenario.java
+++ b/src/com/mostc/pftt/scenario/CLIScenario.java
@@ -1,6 +1,9 @@
 package com.mostc.pftt.scenario;
 
+import java.util.Map;
+
 import com.mostc.pftt.host.AHost;
+import com.mostc.pftt.model.app.PhpUnitTestCase;
 import com.mostc.pftt.model.core.EPhptSection;
 import com.mostc.pftt.model.core.ESAPIType;
 import com.mostc.pftt.model.core.PhpBuild;
@@ -11,8 +14,11 @@ import com.mostc.pftt.model.core.PhptTestCase;
 import com.mostc.pftt.model.sapi.TestCaseGroupKey;
 import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.ITestResultReceiver;
+import com.mostc.pftt.runner.AbstractPhpUnitTestCaseRunner;
 import com.mostc.pftt.runner.AbstractPhptTestCaseRunner;
+import com.mostc.pftt.runner.CliPhpUnitTestCaseRunner;
 import com.mostc.pftt.runner.CliPhptTestCaseRunner;
+import com.mostc.pftt.runner.HttpPhpUnitTestCaseRunner;
 import com.mostc.pftt.runner.LocalPhptTestPackRunner.PhptThread;
 
 /** Tests the Command Line Interface(CLI) for running PHP.
@@ -84,5 +90,10 @@ public class CliScenario extends AbstractSAPIScenario {
        public boolean willSkip(ConsoleManager cm, ITestResultReceiver twriter, 
AHost host, ScenarioSet scenario_set, ESAPIType type, PhpBuild build, 
PhptTestCase test_case) throws Exception {
                return CliPhptTestCaseRunner.willSkip(cm, twriter, host, 
scenario_set, type, build, test_case);
        }
+       
+       @Override
+       public AbstractPhpUnitTestCaseRunner 
createPhpUnitTestCaseRunner(ConsoleManager cm, ITestResultReceiver twriter, 
Map<String, String> globals, Map<String, String> env, AHost runner_host, 
ScenarioSet scenario_set, PhpBuild build, PhpUnitTestCase test_case, String 
my_temp_dir, Map<String, String> constants, String include_path, String[] 
include_files) {
+               return new CliPhpUnitTestCaseRunner(twriter, globals, env, cm, 
runner_host, scenario_set, build, test_case, my_temp_dir, constants, 
test_case.php_unit_dist.getIncludePath(), 
test_case.php_unit_dist.getIncludeFiles());
+       }
 
 } // end public class CliScenario
diff --git a/src/com/mostc/pftt/scenario/ZendOptimizerPlusScenario.java 
b/src/com/mostc/pftt/scenario/ZendOptimizerPlusScenario.java
index fd8f986..8838790 100644
--- a/src/com/mostc/pftt/scenario/ZendOptimizerPlusScenario.java
+++ b/src/com/mostc/pftt/scenario/ZendOptimizerPlusScenario.java
@@ -6,6 +6,16 @@ import com.mostc.pftt.model.core.PhpBuild;
 import com.mostc.pftt.model.core.PhpIni;
 import com.mostc.pftt.results.ConsoleManager;
 
+/** The Zend Optimizer+ provides faster PHP execution through opcode caching 
and optimization.
+ * It improves PHP performance by storing precompiled script bytecode in the 
shared memory. This
+ * eliminates the stages of reading code from the disk and compiling it on 
future access. In
+ * addition, it applies a few bytecode optimization patterns that make code 
execution faster.
+ * 
+ * @see https://github.com/zend-dev/ZendOptimizerPlus
+ * @see https://github.com/OSTC/ZendOptimizerPlus - fork for Windows/PHP on 
Windows
+ *
+ */
+
 public class ZendOptimizerPlusScenario extends AbstractCodeCacheScenario {
 
        @Override
@@ -20,18 +30,37 @@ public class ZendOptimizerPlusScenario extends 
AbstractCodeCacheScenario {
 
        @Override
        public boolean setup(ConsoleManager cm, Host host, PhpBuild build, 
PhpIni ini) {
-               // TODO Auto-generated method stub
-               return false;
+               // assume SO is in same directory as PHP extensions
+               String dll_path = ini.getExtensionDir() + "/ZendOptimizerPlus." 
+ (host.isWindows() ? "dll" : "so" );
+               
+               // must be absolute path to ZendOptimizerPlus.so
+               ini.putMulti("zend_extension", dll_path);
+               
+               // CRITICAL: for CliScenario
+               ini.putSingle("zend_optimizerplus.enable_cli", 1);
+
+               // recommended settings, @see 
https://github.com/zend-dev/ZendOptimizerPlus
+               // (recommended settings differ from some of the documented 
default settings)
+               ini.putSingle("zend_optimizerplus.memory_consumption", 128);
+               ini.putSingle("zend_optimizerplus.interned_strings_buffer", 8);
+               ini.putSingle("zend_optimizerplus.max_accelerated_files", 4000);
+               ini.putSingle("zend_optimizerplus.revalidate_freq", 60);
+               ini.putSingle("zend_optimizerplus.save_comments", 0);
+               ini.putSingle("zend_optimizerplus.fast_shutdown", 1);
+               ini.putSingle("zend_optimizerplus.enable_file_override", 1);
+               
+               return true;
        }
 
        @Override
        public String getName() {
-               return "ZendOptimizer+";
+               // use 'plus' instead of + symbol which may cause problems (ex: 
on certain filesystems)
+               return "ZendOptimizerPlus";
        }
 
        @Override
        public boolean isImplemented() {
-               return false;
+               return true;
        }
        
-}
+} // end public class ZendOptimizerPlusScenario

Reply via email to