Commit:    6d76acfba8d1e52bb593921b396be3ef748866c4
Author:    Matt Ficken <v-maf...@microsoft.com>         Thu, 12 Sep 2013 
15:17:58 -0700
Parents:   17bc5740700d8e3f943a766d866a058c14be6946
Branches:  master

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

Log:
adding Host#getPfttConfDir and Host#getPfttCacheDir

Changed paths:
  M  src/com/github/mattficken/io/ArrayUtil.java
  M  src/com/mostc/pftt/host/AHost.java
  M  src/com/mostc/pftt/host/CommonCommandManager.java
  M  src/com/mostc/pftt/host/Host.java
  M  src/com/mostc/pftt/host/LocalHost.java
  M  src/com/mostc/pftt/host/RemoteHost.java
  M  src/com/mostc/pftt/host/SSHHost.java
  M  src/com/mostc/pftt/host/TempFileExecOutput.java
  M  src/com/mostc/pftt/model/custom/NTFSACL.java
  M  src/com/mostc/pftt/scenario/EnchantScenario.java
  M  src/com/mostc/pftt/scenario/OpcacheScenario.java
  M  src/com/mostc/pftt/scenario/SMBCAScenario.java
  M  src/com/mostc/pftt/scenario/SMBDFSScenario.java
  M  src/com/mostc/pftt/scenario/SMBDeduplicationScenario.java
  M  src/com/mostc/pftt/scenario/Scenario.java
  M  src/com/mostc/pftt/scenario/ScenarioSet.java
  M  src/com/mostc/pftt/scenario/ScenarioSetSetup.java
  M  src/com/mostc/pftt/scenario/WinCacheUScenario.java
  M  src/com/mostc/pftt/scenario/XDebugProfilingScenario.java
  M  src/com/mostc/pftt/scenario/app/JoomlaScenario.groovy
  M  src/com/mostc/pftt/util/HostEnvUtil.java
  M  src/com/mostc/pftt/util/WinDebugManager.java

diff --git a/src/com/github/mattficken/io/ArrayUtil.java 
b/src/com/github/mattficken/io/ArrayUtil.java
index 8a4d692..7838186 100644
--- a/src/com/github/mattficken/io/ArrayUtil.java
+++ b/src/com/github/mattficken/io/ArrayUtil.java
@@ -135,6 +135,8 @@ public class ArrayUtil {
        }
        
        public static <E extends Object> List<E> toList(E[] e) {
+               if (e==null)
+                       return new ArrayList<E>(0); // TODO temp
                ArrayList<E> o = new ArrayList<E>(e.length);
                for ( int i=0 ; i < e.length ; i++ )
                        o.add(e[i]);
diff --git a/src/com/mostc/pftt/host/AHost.java 
b/src/com/mostc/pftt/host/AHost.java
index 6e2fd4f..f84b37f 100644
--- a/src/com/mostc/pftt/host/AHost.java
+++ b/src/com/mostc/pftt/host/AHost.java
@@ -284,6 +284,7 @@ public abstract class AHost extends Host implements 
IProgramRunner {
                        return isWindows() ? getPhpSdkDir() + 
"\\PFTT\\Current\\" : getPhpSdkDir() + "/PFTT/current/";
                }
        }
+       
        @Override
        public String getPhpSdkDir() {
                if (StringUtil.isNotEmpty(php_sdk_dir))
@@ -671,14 +672,14 @@ public abstract class AHost extends Host implements 
IProgramRunner {
        
        private boolean reported_7zip_already_installed = false;
        private static void install7Zip(ConsoleManager cm, AHost src_host, 
AHost dst_host) throws Exception {
-               final String src_7z_path = 
src_host.getPfttDir()+"\\bin\\7za.exe";
+               final String src_7z_path = src_host.getPfttBinDir()+"\\7za.exe";
                if (!src_host.exists(src_7z_path)) {
                        if (cm!=null)
                                cm.println(EPrintType.WARNING, "install7Zip", 
"7za.exe not found on source: "+src_host);
                        return;
                }
                
-               final String dst_7z_path = 
dst_host.getPfttDir()+"\\bin\\7za.exe";
+               final String dst_7z_path = dst_host.getPfttBinDir()+"\\7za.exe";
                
                if (dst_host.exists(dst_7z_path) && 
src_host.getSize(src_7z_path)==dst_host.getSize(dst_7z_path)) {
                        if (dst_host.reported_7zip_already_installed)
@@ -721,7 +722,7 @@ public abstract class AHost extends Host implements 
IProgramRunner {
                if (cm!=null)
                        cm.println(EPrintType.IN_PROGRESS, getClass(), 
"decompress output_dir="+output_dir+" zip7_file="+zip7_file);
                
-               String cmd = silenceCmd(getPfttDir()+"\\bin\\7za x -mx=9 
-mmt="+getCPUCount()+" -bd -y -o"+output_dir+" "+zip7_file);
+               String cmd = silenceCmd(getPfttBinDir()+"\\7za x -mx=9 
-mmt="+getCPUCount()+" -bd -y -o"+output_dir+" "+zip7_file);
                return exec(cmd, AHost.ONE_HOUR);
        }
        
@@ -748,7 +749,7 @@ public abstract class AHost extends Host implements 
IProgramRunner {
                // x=9 => highest compression
                // mt=[cpus] => use several threads == number of cpus => 
maximizes speed
                // bd => no progress bar
-               final String cmd = silenceCmd(getPfttDir()+"\\bin\\7za a -t7z 
-m0=lzma -mx=9 -mfb=64 -md=32m -ms=on -mmt="+getCPUCount()+" -bd "+zip7_file+" 
"+src);
+               final String cmd = silenceCmd(getPfttBinDir()+"\\7za a -t7z 
-m0=lzma -mx=9 -mfb=64 -md=32m -ms=on -mmt="+getCPUCount()+" -bd "+zip7_file+" 
"+src);
 
                if (cm!=null)
                        cm.println(EPrintType.IN_PROGRESS, getClass(), 
"compress zip7_file="+zip7_file+" src="+src);
@@ -1136,5 +1137,6 @@ public abstract class AHost extends Host implements 
IProgramRunner {
        }
 
        protected abstract boolean deleteSingleFile(String path);
+       public abstract boolean isBusy();
        
 } // end public abstract class AHost
diff --git a/src/com/mostc/pftt/host/CommonCommandManager.java 
b/src/com/mostc/pftt/host/CommonCommandManager.java
index 1c191b8..270e082 100644
--- a/src/com/mostc/pftt/host/CommonCommandManager.java
+++ b/src/com/mostc/pftt/host/CommonCommandManager.java
@@ -21,7 +21,7 @@ public class CommonCommandManager {
                                win_close_all_handles_lock.tryLock(10, 
TimeUnit.SECONDS);
                        } catch ( InterruptedException ex ) {}
                        try {
-                               handle_out = 
host.execOut(host.getPfttDir()+"\\bin\\handle -accepteula -p "+process_id+" 
-a", 10);
+                               handle_out = 
host.execOut(host.getPfttBinDir()+"\\handle -accepteula -p "+process_id+" -a", 
10);
                        } finally {
                                try {
                                win_close_all_handles_lock.unlock();
@@ -34,7 +34,7 @@ public class CommonCommandManager {
                                        String handle_type = h_part[1];
                                        if (handle_id.endsWith(":") && 
handle_type.equalsIgnoreCase("File")) {
                                                handle_id = 
handle_id.substring(0, handle_id.length()-1);
-                                               String handle_cmd = 
host.getPfttDir()+"\\bin\\handle -accepteula -p "+process_id+" -y -c 
"+handle_id;
+                                               String handle_cmd = 
host.getPfttBinDir()+"\\handle -accepteula -p "+process_id+" -y -c "+handle_id;
                                                try {
                                                        
win_close_all_handles_lock.tryLock(10, TimeUnit.SECONDS);
                                                } catch ( InterruptedException 
ex ) {}
@@ -70,7 +70,7 @@ public class CommonCommandManager {
                                        win_kill_process_lock.tryLock(5, 
TimeUnit.SECONDS);
                                } catch ( InterruptedException ex ) {}
                                try {
-                                       
host.exec(host.getPfttDir()+"\\bin\\pskill -accepteula -t -p "+process_id, 20);
+                                       
host.exec(host.getPfttBinDir()+"\\pskill -accepteula -t -p "+process_id, 20);
                                        //host.exec("TASKKILL /FI \"IMAGENAME 
eq "+image_name+"\" /FI \"PID eq "+process_id+"\" /F /T", 20);
                                } finally {
                                        try {
@@ -82,7 +82,7 @@ public class CommonCommandManager {
                                        win_kill_process_lock.tryLock(5, 
TimeUnit.SECONDS);
                                } catch ( InterruptedException ex ) {}
                                try {                                   
-                                       
host.exec(host.getPfttDir()+"\\bin\\pskill -accepteula -t -p "+process_id, 20);
+                                       
host.exec(host.getPfttBinDir()+"\\pskill -accepteula -t -p "+process_id, 20);
                                        //host.exec("TASKKILL /FI \"IMAGENAME 
eq "+image_name+"\" /FI \"PID eq "+process_id+"\" /F /T", 20);
                                } finally {
                                        try {
diff --git a/src/com/mostc/pftt/host/Host.java 
b/src/com/mostc/pftt/host/Host.java
index 1c91d64..45286f3 100644
--- a/src/com/mostc/pftt/host/Host.java
+++ b/src/com/mostc/pftt/host/Host.java
@@ -606,6 +606,16 @@ public abstract class Host {
        public abstract String getHomeDir();
        public abstract String getPhpSdkDir();
        public abstract String getPfttDir();
+       
+       public String getPfttBinDir() {
+               return joinIntoOnePath(getPfttDir(), "bin");
+       }
+       public String getPfttCacheDir() {
+               return joinIntoOnePath(getPfttDir(), "cache");
+       }
+       public String getPfttConfDir() {
+               return joinIntoOnePath(getPfttDir(), "conf");
+       }
 
        public String joinIntoOnePath(String ...parts) {
                if (parts==null||parts.length==0)
diff --git a/src/com/mostc/pftt/host/LocalHost.java 
b/src/com/mostc/pftt/host/LocalHost.java
index 2ce8ad8..4140526 100644
--- a/src/com/mostc/pftt/host/LocalHost.java
+++ b/src/com/mostc/pftt/host/LocalHost.java
@@ -25,6 +25,7 @@ import java.util.LinkedList;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.regex.Pattern;
@@ -46,7 +47,9 @@ import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.EPrintType;
 import com.mostc.pftt.runner.AbstractTestPackRunner.TestPackRunnerThread;
 import com.mostc.pftt.util.TimerUtil;
+import com.mostc.pftt.util.TimerUtil.ObjectRunnable;
 import com.mostc.pftt.util.TimerUtil.TimerThread;
+import com.mostc.pftt.util.TimerUtil.WaitableRunnable;
 import com.sun.jna.Pointer;
 import com.sun.jna.platform.win32.Kernel32;
 import com.sun.jna.platform.win32.WinNT.HANDLE;
@@ -55,7 +58,7 @@ import com.sun.jna.platform.win32.WinNT.HANDLE;
  * 
  * LocalHost is fairly straightforward for Linux.
  * 
- * Windows has issues running large numbers of processes or large numbers of 
filesystem operations. LocalHost
+ * Windows has many issues running large numbers of processes or large numbers 
of filesystem operations. LocalHost
  * has several special internal mechanisms to try to contain and manage those 
issues so the rest of PFTT doesn't have to deal with them.
  *
  * @see SSHHost
@@ -79,12 +82,47 @@ public class LocalHost extends AHost {
        }
        protected final CommonCommandManager ccm; // share some 'shelling out' 
code with SSHHost
        protected final HashMap<Thread,Object> close_thread_set; // for 
LocalExecHandle#close
+       protected static final AtomicInteger active_proc_counter = new 
AtomicInteger();
        
        public LocalHost() {
                close_thread_set = new HashMap<Thread,Object>();
                ccm = new CommonCommandManager();
        }
        
+       public int getActiveProcessCount() {
+               return staticGetActiveProcessCount();
+       }
+       
+       public int staticGetActiveProcessCount() {
+               return active_proc_counter.get();
+       }
+       
+       protected static final AtomicInteger wait_runnable_thread_counter = new 
AtomicInteger();
+       protected <E extends Object> E runWaitRunnable(String name_prefix, int 
seconds, final ObjectRunnable<E> r) throws Exception {
+               int a = wait_runnable_thread_counter.incrementAndGet();
+               if (a > Math.max(600, getActiveProcessCount()*1.8)) {
+                       int i=0;
+                       do {
+                               try {
+                                       i++;
+                                       Thread.sleep(50*i);
+                               } catch (InterruptedException e) {}
+                       } while (wait_runnable_thread_counter.get() > 
Math.max(400, getActiveProcessCount()*1.4) && i < 40);
+               }
+               WaitableRunnable<E> h;
+               try {
+                       h = TimerUtil.runWaitSeconds(name_prefix, seconds, r);
+               } finally {
+                       wait_runnable_thread_counter.decrementAndGet();
+               }
+               if (h==null)
+                       return null;
+               else if (h.getException()!=null)
+                       throw h.getException();
+               else
+                       return h.getResult();
+       } // end protected E runWaitRunnable
+       
        public static boolean isLocalhostWindows() {
                return is_windows;
        }
@@ -119,13 +157,13 @@ public class LocalHost extends AHost {
                        //
                        //
                        if (!checked_elevate) {
-                               found_elevate = 
exists(getPfttDir()+"\\bin\\elevate.exe");
+                               found_elevate = 
exists(getPfttBinDir()+"\\elevate.exe");
                                
                                checked_elevate = true;
                        }
                        if (found_elevate) {
                                // execute command with this utility that will 
elevate the program using Windows UAC
-                               cmd = getPfttDir() + "\\bin\\elevate "+cmd;
+                               cmd = getPfttBinDir() + "\\elevate "+cmd;
                        }
                }
                
@@ -302,7 +340,7 @@ public class LocalHost extends AHost {
                        this.stdin = stdin;
                        this.stdout = stdout;
                        this.stderr = stderr;
-                       this.image_name = 
StringUtil.unquote(basename(cmd_array[0]));
+                       this.image_name = 
cmd_array==null||cmd_array.length==0?"":StringUtil.unquote(basename(cmd_array[0]));
                        if (isLocalhostWindows()) {
                                if (this.image_name.endsWith(".cmd"))
                                        this.image_name = "cmd.exe"; // 
IMPORTANT: this is how its identified in the Windows process table
@@ -316,6 +354,22 @@ public class LocalHost extends AHost {
                        final Process p = this.process.get();
                        if (p==null)
                                return false;
+                       if (isWindows()) {
+                               Boolean b = null;
+                               try {
+                                       b = runWaitRunnable("IsRunning", 10, 
new ObjectRunnable<Boolean>() {
+                                                       public Boolean run() {
+                                                               return 
doIsRunning(p);
+                                                       }
+                                               });
+                               } catch ( Exception ex ) {}
+                               return b == null ? false : b.booleanValue();
+                       } else {
+                               return doIsRunning(p);
+                       }
+               }
+               
+               protected boolean doIsRunning(Process p) {
                        try {
                                p.exitValue();
                                return false;
@@ -370,11 +424,7 @@ public class LocalHost extends AHost {
                                                for ( int tries = 0 ; tries < 
10 ; tries++ ) {
                                                        // 
                                                        //
-                                                       try {
-                                                               p.exitValue();
-                                                               break; 
-                                                               // process 
terminated, stop trying (or may terminate new process reusing the same id)
-                                                       } catch ( Throwable t ) 
{
+                                                       if (doIsRunning(p)) {
                                                                if 
(stdout!=null) {
                                                                        try {
                                                                                
stdout.close();
@@ -474,7 +524,10 @@ public class LocalHost extends AHost {
                                                                        
t2.printStackTrace();
                                                                }
                                                                //
-                                                       } // end try
+                                                       } else {
+                                                               // process 
terminated, stop trying (or may terminate new process reusing the same id)
+                                                               break;
+                                                       }
                                                } // end for
                                                // by now process should be 
dead/should have stopped writing
                                                // so #exec_copy_lines should 
stop (which will stop blocking whatever called #exec_impl or #exec or #execOut)
@@ -529,11 +582,31 @@ public class LocalHost extends AHost {
                        // ignores STDERR
                        
                        // wait for process exit (shouldn't get here until exit 
or #close though)
+                       final ObjectRunnable<Integer> or = isWindows() ? new 
ObjectRunnable<Integer>() {
+                                       public Integer run() {
+                                               try {
+                                                       return p.exitValue();
+                                               } catch ( Exception ex ) {
+                                                       return null;
+                                               }
+                                       }
+                               } : null;
                        for (int time = 50;wait.get();) {
-                               try {
-                                       exit_code = p.exitValue();
-                                       break;
-                               } catch ( IllegalThreadStateException ex ) {}
+                               /*if (isWindows()) {
+                                       Integer e = null;
+                                       try {
+                                               e = 
runWaitRunnable("ExitValue", 10, or);
+                                       } catch ( Exception ex ) {}
+                                       if (e!=null) {
+                                               exit_code = e.intValue();
+                                               break;
+                                       } // else: process is still running
+                               } else {*/
+                                       try {
+                                               exit_code = p.exitValue();
+                                               break;
+                                       } catch ( IllegalThreadStateException 
ex ) {}
+                               //}
                                try {
                                        Thread.sleep(time);
                                } catch ( InterruptedException ex ) {
@@ -557,13 +630,24 @@ public class LocalHost extends AHost {
                        }
                        //
                        
+                       active_proc_counter.decrementAndGet();
+                       
                        // free up process handle
                        if (process.get()!=null) {
                                // don't call #destroy on this process if 
#close already has
                                //
                                // on Windows, it can block forever
                                try {
-                                       p.destroy();
+                                       if (isWindows()) {
+                                               runWaitRunnable("Destroy", 60, 
new ObjectRunnable<Boolean>() {
+                                                               public Boolean 
run() {
+                                                                       
p.destroy();
+                                                                       return 
true;
+                                                               }
+                                                       });
+                                       } else {
+                                               p.destroy();
+                                       }
                                } catch ( Exception ex ) {}
                        }
                        
@@ -677,9 +761,9 @@ public class LocalHost extends AHost {
                        this.run(output_sb, charset, suspend_seconds);
                        
                        if (a!=null)
-                               a.cancel();
+                               a.close();
                        if (b!=null)
-                               b.cancel();
+                               b.close();
                }
 
                @Override
@@ -765,13 +849,7 @@ public class LocalHost extends AHost {
                return (String[])parts.toArray(new String[]{});
        } // end public static String[] splitCmdString
        
-       static final UncaughtExceptionHandler IGNORE = new 
UncaughtExceptionHandler() {
-                       @Override
-                       public void uncaughtException(Thread arg0, Throwable 
arg1) {
-                       }
-               };
-       @SuppressWarnings("deprecation")
-       protected Process guardStart(final ProcessBuilder builder) throws 
IOException, InterruptedException {
+       protected Process guardStart(final ProcessBuilder builder) throws 
Exception, InterruptedException {
                if (!isWindows())
                        return builder.start();
                
@@ -779,43 +857,14 @@ public class LocalHost extends AHost {
                //             and sometimes CLI
                //
                // call ProcessBuilder#start in separate thread to monitor it
-               final AtomicReference<IOException> ex_ref = new 
AtomicReference<IOException>();
-               final AtomicReference<Process> proc_ref = new 
AtomicReference<Process>();
-               final Thread start_thread = new Thread() {
-                               public void run() {
-                                       try {
-                                               proc_ref.set(builder.start());
-                                               synchronized(proc_ref) {
-                                                       proc_ref.notifyAll();
-                                               }
-                                       } catch ( IOException ex ) {
-                                               ex_ref.set(ex);
-                                       }
+               return runWaitRunnable("ProcessBuilder", 120, new 
ObjectRunnable<Process>() {
+                               public Process run() throws IOException {
+                                       return builder.start();
                                }
-                       };
-               start_thread.setUncaughtExceptionHandler(IGNORE);
-               start_thread.setDaemon(true);
-               start_thread.setName("ProcessBuilder"+start_thread.getName());
-               start_thread.start();
-               // wait up to 120 seconds for ProcessBuilder#start
-               try {
-                       synchronized(proc_ref) {
-                               proc_ref.wait(120000);
-                       }
-               } catch ( Exception ex ) {}
-               Process proc = proc_ref.get();
-               if (proc==null) {
-                       // try to kill off the thread (ProcessBuilder#start is 
native code though)
-                       start_thread.stop(new 
RuntimeException("ProcessBuilder#start timeout (Localhost)"));
-                       
-                       IOException ex = ex_ref.get();
-                       if (ex!=null)
-                               throw ex;
-               }
-               return proc;
+                       });
        } // end protected Process guardStart
        
-       protected LocalExecHandle exec_impl(String[] cmd_array, 
Map<String,String> env, String chdir, byte[] stdin_data) throws IOException, 
InterruptedException {
+       protected LocalExecHandle exec_impl(String[] cmd_array, 
Map<String,String> env, String chdir, byte[] stdin_data) throws Exception, 
InterruptedException {
                Process process = null;
                {
                        ProcessBuilder builder = new ProcessBuilder(cmd_array);
@@ -880,6 +929,7 @@ public class LocalHost extends AHost {
                if (process==null)
                        return new LocalExecHandle(process, null, null, null, 
null);
                
+               active_proc_counter.incrementAndGet();
                OutputStream stdin = process.getOutputStream();
                
                if (stdin_data!=null && stdin_data.length>0) {
@@ -1177,5 +1227,13 @@ public class LocalHost extends AHost {
                // TODO Auto-generated method stub
                return false;
        }
+
+       @Override
+       public boolean isBusy() {
+               // REMINDER: processes launched by cmd.exe on Windows 
automatically create
+               //           a second process (conhost.exe) to manage the 
console
+               //           so the actual number of processes will be doubled 
on Windows
+               return active_proc_counter.get() < (isWindows() ? 192 : 400 );
+       }
        
 } // end public class Host
diff --git a/src/com/mostc/pftt/host/RemoteHost.java 
b/src/com/mostc/pftt/host/RemoteHost.java
index db4aeb6..c6a56ce 100644
--- a/src/com/mostc/pftt/host/RemoteHost.java
+++ b/src/com/mostc/pftt/host/RemoteHost.java
@@ -22,13 +22,13 @@ public abstract class RemoteHost extends AHost {
        public ExecOutput execElevatedOut(String cmd, int timeout_sec, 
Map<String, String> env, byte[] stdin_data, Charset charset, String chdir, 
TestPackRunnerThread test_thread, int slow_timeout_sec) throws Exception {
                if (isWindows()) {
                        if (!checked_elevate) {
-                               found_elevate = 
exists(getPfttDir()+"\\bin\\elevate.exe");
+                               found_elevate = 
exists(getPfttBinDir()+"\\elevate.exe");
                                
                                checked_elevate = true;
                        }
                        if (found_elevate) {
                                // execute command with this utility that will 
elevate the program using Windows UAC
-                               cmd = getPfttDir() + "\\bin\\elevate "+cmd;
+                               cmd = getPfttBinDir() + "\\elevate "+cmd;
                        }
                }
                
diff --git a/src/com/mostc/pftt/host/SSHHost.java 
b/src/com/mostc/pftt/host/SSHHost.java
index 3409d9c..5fe1288 100644
--- a/src/com/mostc/pftt/host/SSHHost.java
+++ b/src/com/mostc/pftt/host/SSHHost.java
@@ -869,4 +869,10 @@ public class SSHHost extends RemoteHost {
                return null;
        }
 
+       @Override
+       public boolean isBusy() {
+               // hard to check so don't check for now
+               return false;
+       }
+
 } // end public class SSHHost
diff --git a/src/com/mostc/pftt/host/TempFileExecOutput.java 
b/src/com/mostc/pftt/host/TempFileExecOutput.java
index fdb3fea..7eea82c 100644
--- a/src/com/mostc/pftt/host/TempFileExecOutput.java
+++ b/src/com/mostc/pftt/host/TempFileExecOutput.java
@@ -14,8 +14,14 @@ public class TempFileExecOutput extends ExecOutput {
                this.output = eo.output;
                this.temp_file = temp_file;
        }
+       
+       public TempFileExecOutput cleanupSuccess(AHost host) {
+               if (isSuccess())
+                       cleanup(host);
+               return this;
+       }
 
-       public boolean cleanupIfSuccess(AHost host) {
+       public boolean cleanupIsSuccess(AHost host) {
                if (isSuccess()) {
                        cleanup(host);
                        return true;
diff --git a/src/com/mostc/pftt/model/custom/NTFSACL.java 
b/src/com/mostc/pftt/model/custom/NTFSACL.java
index f968d30..e21e678 100644
--- a/src/com/mostc/pftt/model/custom/NTFSACL.java
+++ b/src/com/mostc/pftt/model/custom/NTFSACL.java
@@ -586,7 +586,7 @@ public class NTFSACL {
        
        protected static void setACL(Host host, String args) throws Exception {
                //WL( '\t' + 'setacl' + args );
-               host.exec(host.getPfttDir()+"/bin/setacl " + args, 
Host.FOUR_HOURS );
+               host.exec(host.getPfttBinDir()+"/setacl " + args, 
Host.FOUR_HOURS );
        }
        
 } // end public class NTFSACL
diff --git a/src/com/mostc/pftt/scenario/EnchantScenario.java 
b/src/com/mostc/pftt/scenario/EnchantScenario.java
index e995246..99be323 100644
--- a/src/com/mostc/pftt/scenario/EnchantScenario.java
+++ b/src/com/mostc/pftt/scenario/EnchantScenario.java
@@ -28,7 +28,7 @@ public class EnchantScenario extends INIScenario {
                        // LATER php on non-windows may need a dictionary too ??
                        String dst = build.getBuildPath()+"/share/";
                        if (!host.exists(dst)) {
-                               
host.copyElevated(host.getPfttDir()+"/cache/util/enchant/share", dst);
+                               
host.copyElevated(host.getPfttCacheDir()+"/util/enchant/share", dst);
                        
                                
                                // make sure libraries are where they need to 
be also
@@ -63,7 +63,7 @@ public class EnchantScenario extends INIScenario {
        }
 
        public static String getDictionaryFile(AHost host) {
-               return 
host.getPfttDir()+"/cache/util/enchant/share/myspell/dicts/en_US.dic";
+               return 
host.getPfttCacheDir()+"/util/enchant/share/myspell/dicts/en_US.dic";
        }
 
 } // end public class EnchantScenario
diff --git a/src/com/mostc/pftt/scenario/OpcacheScenario.java 
b/src/com/mostc/pftt/scenario/OpcacheScenario.java
index 7a412ad..a284134 100644
--- a/src/com/mostc/pftt/scenario/OpcacheScenario.java
+++ b/src/com/mostc/pftt/scenario/OpcacheScenario.java
@@ -97,22 +97,22 @@ public class OpcacheScenario extends CodeCacheScenario {
        
        @Overridable
        protected DllVersion getDllPath53TS(Host host) {
-               return new 
DllVersion(host.getPfttDir()+"/cache/dep/opcache/php_opcache-7.0.2-5.3-ts-vc9-x86/php_opcache.dll",
 "7.0.2");
+               return new 
DllVersion(host.getPfttCacheDir()+"/dep/opcache/php_opcache-7.0.2-5.3-ts-vc9-x86/php_opcache.dll",
 "7.0.2");
        }
        
        @Overridable
        protected DllVersion getDllPath53NTS(Host host) {
-               return new 
DllVersion(host.getPfttDir()+"/cache/dep/opcache/php_opcache-7.0.2-5.3-nts-vc9-x86/php_opcache.dll",
 "7.0.2");
+               return new 
DllVersion(host.getPfttCacheDir()+"/dep/opcache/php_opcache-7.0.2-5.3-nts-vc9-x86/php_opcache.dll",
 "7.0.2");
        }
        
        @Overridable
        protected DllVersion getDllPath54TS(Host host) {
-               return new 
DllVersion(host.getPfttDir()+"/cache/dep/opcache/php_opcache-7.0.2-5.4-ts-vc9-x86/php_opcache.dll",
 "7.0.2");
+               return new 
DllVersion(host.getPfttCacheDir()+"/dep/opcache/php_opcache-7.0.2-5.4-ts-vc9-x86/php_opcache.dll",
 "7.0.2");
        }
        
        @Overridable
        protected DllVersion getDllPath54NTS(Host host) {
-               return new 
DllVersion(host.getPfttDir()+"/cache/dep/opcache/php_opcache-7.0.2-5.4-nts-vc9-x86/php_opcache.dll",
 "7.0.2");
+               return new 
DllVersion(host.getPfttCacheDir()+"/dep/opcache/php_opcache-7.0.2-5.4-nts-vc9-x86/php_opcache.dll",
 "7.0.2");
        }
        
        public DllVersion getDllPath(ConsoleManager cm, Host host, PhpBuild 
build) {
diff --git a/src/com/mostc/pftt/scenario/SMBCAScenario.java 
b/src/com/mostc/pftt/scenario/SMBCAScenario.java
index 04fcf8a..4cf63e0 100644
--- a/src/com/mostc/pftt/scenario/SMBCAScenario.java
+++ b/src/com/mostc/pftt/scenario/SMBCAScenario.java
@@ -44,7 +44,7 @@ public class SMBCAScenario extends SMBScenario {
        protected boolean createShareWindows(SMBStorageDir dir, ConsoleManager 
cm) throws Exception {
                TempFileExecOutput teo = remote_host.powershell(getClass(), cm, 
"New-SmbShare -Name "+dir.share_name+" -Path "+dir.remote_path+" -Scope 
"+remote_host.getHostname()+" -FullControl 
"+remote_host.getHostname()+"\\"+remote_host.getUsername(), AHost.ONE_MINUTE);
                teo.printCommandAndOutput(EPrintType.CLUE, getClass(), cm);
-               return teo.cleanupIfSuccess(remote_host);
+               return teo.cleanupIsSuccess(remote_host);
        }
 
        @Override
diff --git a/src/com/mostc/pftt/scenario/SMBDFSScenario.java 
b/src/com/mostc/pftt/scenario/SMBDFSScenario.java
index f122148..3fc2b0e 100644
--- a/src/com/mostc/pftt/scenario/SMBDFSScenario.java
+++ b/src/com/mostc/pftt/scenario/SMBDFSScenario.java
@@ -242,7 +242,7 @@ public class SMBDFSScenario extends SMBScenario {
                try {
                        TempFileExecOutput teo = 
remote_host.powershell(getClass(), cm, ps_sb, AHost.FOUR_HOURS);
                        teo.printCommandAndOutput(EPrintType.CLUE, getClass(), 
cm);
-                       if (teo.cleanupIfSuccess(remote_host)) {
+                       if (teo.cleanupIsSuccess(remote_host)) {
                                
                                cm.println(EPrintType.COMPLETED_OPERATION, 
getClass(), "DFS Feature Installed");
                                        
diff --git a/src/com/mostc/pftt/scenario/SMBDeduplicationScenario.java 
b/src/com/mostc/pftt/scenario/SMBDeduplicationScenario.java
index 74e17e5..d348abb 100644
--- a/src/com/mostc/pftt/scenario/SMBDeduplicationScenario.java
+++ b/src/com/mostc/pftt/scenario/SMBDeduplicationScenario.java
@@ -108,7 +108,7 @@ public class SMBDeduplicationScenario extends SMBScenario {
                                
                                final TempFileExecOutput eo = 
remote_host.powershell(getClass(), cm, "Start-Dedupjob -Volume "+volume+" -Type 
Optimization -Wait", AHost.FOUR_HOURS);
                                eo.printCommandAndOutput(EPrintType.CLUE, 
getClass(), cm);
-                               if (eo.cleanupIfSuccess(remote_host)) {
+                               if (eo.cleanupIsSuccess(remote_host)) {
                                        
                                        //
                                        // log REPARSEPOINT QUERY to show if 
reparse point/deduplication was really setup
@@ -164,7 +164,7 @@ public class SMBDeduplicationScenario extends SMBScenario {
                        cm.println(EPrintType.IN_PROGRESS, getClass(), 
"Starting to Install Deduplication on: "+remote_host);
                        TempFileExecOutput teo = 
remote_host.powershell(getClass(), cm, ps_sb, AHost.ONE_MINUTE * 10);
                        teo.printCommandAndOutput(EPrintType.CLUE, getClass(), 
cm);
-                       if (teo.cleanupIfSuccess(remote_host)) {
+                       if (teo.cleanupIsSuccess(remote_host)) {
                                // don't delete tmp_file if it failed to help 
user see why
                                
                                cm.println(EPrintType.IN_PROGRESS, getClass(), 
"Deduplication Feature Installed.");
diff --git a/src/com/mostc/pftt/scenario/Scenario.java 
b/src/com/mostc/pftt/scenario/Scenario.java
index b0d2658..62997a0 100644
--- a/src/com/mostc/pftt/scenario/Scenario.java
+++ b/src/com/mostc/pftt/scenario/Scenario.java
@@ -46,7 +46,6 @@ public abstract class Scenario {
                return false;
        }
        
-       // TODO
        @Overridable
        public Class<?> getSerialKey(EScenarioSetPermutationLayer layer) {
                return getClass();
@@ -204,6 +203,14 @@ public abstract class Scenario {
                        scenario_set.add(new EnchantScenario());
        }
        
+       public int getApprovedInitialThreadPoolSize(AHost host, int threads) {
+               return threads;
+       }
+       
+       public int getApprovedMaximumThreadPoolSize(AHost host, int threads) {
+               return threads;
+       }
+       
        /** writes Scenario to XML
         * 
         * @param serial
diff --git a/src/com/mostc/pftt/scenario/ScenarioSet.java 
b/src/com/mostc/pftt/scenario/ScenarioSet.java
index f6da09c..80dba2f 100644
--- a/src/com/mostc/pftt/scenario/ScenarioSet.java
+++ b/src/com/mostc/pftt/scenario/ScenarioSet.java
@@ -231,12 +231,28 @@ public class ScenarioSet extends ArrayList<Scenario> {
         * @return
         */
        public static List<ScenarioSet> 
permuteScenarioSets(EScenarioSetPermutationLayer layer, List<Scenario> 
scenarios) {
-               HashMap<Class<?>,List<Scenario>> map = new 
HashMap<Class<?>,List<Scenario>>();
+               HashMap<Object,List<ScenarioSet>> version_map = new 
HashMap<Object,List<ScenarioSet>>();
+               for ( Scenario s : scenarios ) {
+                       if (!(s instanceof DatabaseScenario))
+                               continue;
+                       // TODO temp
+                       Object v = ((DatabaseScenario)s).version;
+                       version_map.put(v, p(layer, scenarios));
+               }
+               if (version_map.isEmpty())
+                       return p(layer, scenarios);
+               List<ScenarioSet> out = new ArrayList<ScenarioSet>();
+               for ( List<ScenarioSet> a : version_map.values() )
+                       out.addAll(a);
+               return out;
+       }
+       static List<ScenarioSet> p(EScenarioSetPermutationLayer layer, 
List<Scenario> scenarios) {
+               HashMap<Object,List<Scenario>> map = new 
HashMap<Object,List<Scenario>>();
                for ( Scenario scenario : scenarios ) {
                        if (layer!=null && layer.reject(scenario))
                                continue;
                        
-                       Class<?> clazz = scenario.getSerialKey(layer);
+                       Object clazz = scenario.getSerialKey(layer);
                        //
                        List<Scenario> list = map.get(clazz);
                        if (list==null) {
@@ -319,10 +335,12 @@ public class ScenarioSet extends ArrayList<Scenario> {
                        name = s.processNameAndVersionInfo(name);
                return name;
        }
-
+       
        public static ScenarioSet parse(String name) {
+               // TODO result_pack_mgr as param, throw NPE if not given (this 
method is only to be used there)
                ScenarioSet s = new ScenarioSet();
                s.str = name;
+               s.sorted = true;
                return s;
        }
        
diff --git a/src/com/mostc/pftt/scenario/ScenarioSetSetup.java 
b/src/com/mostc/pftt/scenario/ScenarioSetSetup.java
index 3331ea9..c55f820 100644
--- a/src/com/mostc/pftt/scenario/ScenarioSetSetup.java
+++ b/src/com/mostc/pftt/scenario/ScenarioSetSetup.java
@@ -1,5 +1,6 @@
 package com.mostc.pftt.scenario;
 
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -88,6 +89,14 @@ public class ScenarioSetSetup implements IClosable {
                this.setups = setups;
                this.name_version = name_version;
        }
+       
+       public Collection<Scenario> getScenarios() {
+               return setups.keySet();
+       }
+       
+       public Collection<IScenarioSetup> getSetups() {
+               return setups.values();
+       }
 
        public String getNameWithVersionInfo() {
                return name_version;
diff --git a/src/com/mostc/pftt/scenario/WinCacheUScenario.java 
b/src/com/mostc/pftt/scenario/WinCacheUScenario.java
index d84ef48..2b37fe4 100644
--- a/src/com/mostc/pftt/scenario/WinCacheUScenario.java
+++ b/src/com/mostc/pftt/scenario/WinCacheUScenario.java
@@ -1,6 +1,7 @@
 package com.mostc.pftt.scenario;
 
 import com.github.mattficken.Overridable;
+import com.mostc.pftt.host.AHost;
 import com.mostc.pftt.host.Host;
 import com.mostc.pftt.model.core.EBuildBranch;
 import com.mostc.pftt.model.core.PhpBuild;
@@ -18,18 +19,28 @@ import com.mostc.pftt.results.ConsoleManager;
 // TODO mediawiki support
 // TODO windebug integration - wincache includes the .PDB symbol file
 public abstract class WinCacheUScenario extends UserCacheScenario {
+       
+       @Override
+       public int getApprovedInitialThreadPoolSize(AHost host, int threads) {
+               return host.getCPUCount() * 2;
+       }
+       
+       @Override
+       public int getApprovedMaximumThreadPoolSize(AHost host, int threads) {
+               return host.getCPUCount() * 3;
+       }
 
        @Overridable
        protected String getDllPath55Plus(Host host) {
-               return 
host.getPfttDir()+"/cache/dep/wincache/wincache-1.3.4.1-dev-5.5-nts-vc11-x86/php_wincache.dll";
+               return 
host.getPfttCacheDir()+"/dep/wincache/wincache-1.3.5-5.5-nts-vc11-x86/php_wincache.dll";
        }
        @Overridable
        protected String getDllPath54(Host host) {
-               return 
host.getPfttDir()+"/cache/dep/wincache/wincache-1.3.4-5.4-nts-vc9-x86/php_wincache.dll";
+               return 
host.getPfttCacheDir()+"/dep/wincache/wincache-1.3.4-5.4-nts-vc9-x86/php_wincache.dll";
        }
        @Overridable
        protected String getDllPath53(Host host) {
-               return 
host.getPfttDir()+"/cache/dep/wincache/wincache-1.3.4-5.3-nts-vc9-x86/php_wincache.dll";
+               return 
host.getPfttCacheDir()+"/dep/wincache/wincache-1.3.4-5.3-nts-vc9-x86/php_wincache.dll";
        }
        
        // @see http://us.php.net/manual/en/wincache.configuration.php
@@ -87,10 +98,18 @@ public abstract class WinCacheUScenario extends 
UserCacheScenario {
        
        @Override
        public boolean isSupported(ConsoleManager cm, Host host, PhpBuild 
build, ScenarioSet scenario_set) {
-               // don't run WinCache on Apache-ModPHP (Apache CGI probably ok)
-               //
-               // not sure if its supported on scenarios other than CLI or IIS 
(or builtin-web?)
-               return host.isWindows() && build.isNTS(host) && 
!scenario_set.contains(ApacheModPHPScenario.class);
+               return host.isWindows() 
+                               && build.isX86() 
+                               && build.isNTS(host) 
+                               && (
+                                               // LATER? Apache FastCGI 
support on Windows
+                                               
scenario_set.contains(CliScenario.class)
+                                               || 
scenario_set.contains(IISScenario.class)
+                                               // WinCacheU should support 
builtin web server b/c (low priority though):
+                                               //  web developers use 
wincache's user cache in their applications
+                                               //  web developers like to use 
the builtin web server to run/test their application
+                                               || 
scenario_set.contains(BuiltinWebServerScenario.class)
+                                               );
        }
 
        @Override
diff --git a/src/com/mostc/pftt/scenario/XDebugProfilingScenario.java 
b/src/com/mostc/pftt/scenario/XDebugProfilingScenario.java
index 2854283..51d46f0 100644
--- a/src/com/mostc/pftt/scenario/XDebugProfilingScenario.java
+++ b/src/com/mostc/pftt/scenario/XDebugProfilingScenario.java
@@ -1,8 +1,11 @@
 package com.mostc.pftt.scenario;
 
+import com.mostc.pftt.host.AHost;
 import com.mostc.pftt.host.Host;
 import com.mostc.pftt.model.core.PhpBuild;
 import com.mostc.pftt.model.core.PhpIni;
+import com.mostc.pftt.results.AbstractPhpUnitRW;
+import com.mostc.pftt.results.AbstractPhptRW;
 import com.mostc.pftt.results.ConsoleManager;
 
 /**
@@ -12,26 +15,76 @@ import com.mostc.pftt.results.ConsoleManager;
  */
 
 public class XDebugProfilingScenario extends XDebugScenario {
+       public static final String OUTPUT_DIR = "xdebug.profiler_output_dir";
 
        @Override
        public String getName() {
                return "XDebug-Profiling";
        }
        
+       public IScenarioSetup setup(ConsoleManager cm, Host host, PhpBuild 
build, ScenarioSet scenario_set, EScenarioSetPermutationLayer layer) {
+               return new ProfilingScenarioSetup();
+       }
+       
        @Override
        public IScenarioSetup setup(ConsoleManager cm, Host host, PhpBuild 
build, PhpIni ini) {
                if (super.setup(cm, host, build, ini)==SETUP_FAILED)
                        return SETUP_FAILED;
                
+               setup(ini);
+               // #setPHPTWriter and #setPhpUnitWriter get called first to 
store it in result-pack
+               //       @see 
AbstractLocalTestPackRunner$TestPackThread#exec_jobs
+               // store in $TEMP unless/until they are called though (as a 
backup, this shouldn't happen though)
+               ini.putSingle(OUTPUT_DIR, host.getTempDir());
+               
+               return new ProfilingScenarioSetup();
+       }
+       
+       protected void setup(PhpIni ini) {
                ini.putSingle("xdebug.profiler_append", "0");
                ini.putSingle("xdebug.profiler_enable", "1");
-               // TODO include test name
                // include script name in file name
                ini.putSingle("xdebug.profiler_output_name", 
"pftt.%p.%s.cachegrind");
-               // TODO store in test-pack
-               ini.putSingle("xdebug.profiler_output_dir", host.getTempDir());
+       }
+       
+       protected class ProfilingScenarioSetup extends SimpleScenarioSetup {
+               
+               @Override
+               public boolean isNeededPhpUnitWriter() {
+                       return true;
+               }
+               
+               @Override
+               public void setPhpUnitWriter(AHost runner_host, 
ScenarioSetSetup scenario_set_setup, PhpBuild build, PhpIni ini, 
AbstractPhpUnitRW phpunit) {
+                       setup(ini);
+                       ini.putSingle(OUTPUT_DIR, phpunit.getPath());
+               }
+               
+               @Override
+               public void setPHPTWriter(AHost runner_host, ScenarioSetSetup 
scenario_set_setup, PhpBuild build, PhpIni ini, AbstractPhptRW phpt) {
+                       setup(ini);
+                       ini.putSingle(OUTPUT_DIR, phpt.getPath());
+               }
+               
+               @Override
+               public boolean isNeededPhptWriter() {
+                       return true;
+               }
+               
+               @Override
+               public String getNameWithVersionInfo() {
+                       return getName(); // TODO auto detect
+               }
+
+               @Override
+               public String getName() {
+                       return XDebugProfilingScenario.this.getName();
+               }
+
+               @Override
+               public void close(ConsoleManager cm) {
+               }
                
-               return SETUP_SUCCESS;
        }
        
 }
diff --git a/src/com/mostc/pftt/scenario/app/JoomlaScenario.groovy 
b/src/com/mostc/pftt/scenario/app/JoomlaScenario.groovy
index eec9073..c6d61ba 100644
--- a/src/com/mostc/pftt/scenario/app/JoomlaScenario.groovy
+++ b/src/com/mostc/pftt/scenario/app/JoomlaScenario.groovy
@@ -30,7 +30,7 @@ public class JoomlaScenario extends ZipDbApplication {
 
        @Override
        public boolean isImplemented() {
-               return false;
+               return true;
        }
 
        @Override
@@ -42,7 +42,7 @@ public class JoomlaScenario extends ZipDbApplication {
        protected boolean configure(ConsoleManager cm, Host host, PhpBuild 
build, ScenarioSet scenario_set, String app_dir) {
                // TODO Auto-generated method stub
                
-               host.open("joomla/joomla.xml");
+               /*host.open("joomla/joomla.xml");
                def xml = """
                  <?xml version="1.0" encoding="UTF-8" ?> 
                  - <extension version="3.0" type="file" method="upgrade">
@@ -95,9 +95,9 @@ public class JoomlaScenario extends ZipDbApplication {
                    <server 
type="collection">http://update.joomla.org/jed/list.xml</server> 
                    </updateservers>
                    </extension>
-               """
+               """*/
 
-               return false;
+               return true;
        }
 
 }
diff --git a/src/com/mostc/pftt/util/HostEnvUtil.java 
b/src/com/mostc/pftt/util/HostEnvUtil.java
index 4ff766c..a59f41d 100644
--- a/src/com/mostc/pftt/util/HostEnvUtil.java
+++ b/src/com/mostc/pftt/util/HostEnvUtil.java
@@ -74,8 +74,8 @@ public final class HostEnvUtil {
                        
                        regDel(cm, host, "HKLM\\Software\\Microsoft\\Windows 
NT\\CurrentVersion\\AeDebug", "Debugger");
                        // IMPORTANT: don't delete this key, change the value 
otherwise (if windbg installed) werfault.exe will
-                       //            still launch windbg... won't if set to 
0x2.
-                       regQueryAdd(cm, host, 
"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", "Auto", 
"0x2", REG_DWORD);
+                       //            still launch windbg... won't if set to 0x1
+                       regQueryAdd(cm, host, 
"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", "Auto", 
"0x1", REG_DWORD);
                }
                
                if ( a || b || c ) {
diff --git a/src/com/mostc/pftt/util/WinDebugManager.java 
b/src/com/mostc/pftt/util/WinDebugManager.java
index c195311..94dc9e7 100644
--- a/src/com/mostc/pftt/util/WinDebugManager.java
+++ b/src/com/mostc/pftt/util/WinDebugManager.java
@@ -123,7 +123,7 @@ public class WinDebugManager extends DebuggerManager {
                        // -n => noisy symbol load => provide extra info about 
symbol loading to trace any symbol problems
                        sb.append(" -n");
                        // -WF => provide default workspace file, which will 
automatically dock the command window within the windebug window
-                       String workspace_file = 
host.fixPath(host.joinIntoOnePath(host.getPfttDir(), 
"\\bin\\pftt_workspace.WEW"));
+                       String workspace_file = 
host.fixPath(host.joinIntoOnePath(host.getPfttBinDir(), 
"\\pftt_workspace.WEW"));
                        if (host.exists(workspace_file)) {
                                sb.append(" -WF 
\"");sb.append(workspace_file);sb.append("\"");
                        }
-- 
PHP Quality Assurance Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to