Commit:    26701b6fd15e9d5efa8218a60b9af5135959e40e
Author:    Matt Ficken <v-maf...@microsoft.com>         Thu, 24 Jan 2013 
00:13:53 -0800
Parents:   602a73184c083b98c83afc29f42dfe2816c7bba0
Branches:  master

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

Log:
various bug fixes


Former-commit-id: 3f4f4643d17c32346430d7d0259ba7be0fd4b4b3

Changed paths:
  M  .classpath
  A  bin/SetACL.exe
  M  bin/pftt.cmd
  A  bin/ssh_server.cmd
  D  lib/SSHD_fat.jar
  A  lib/log4j-1.2.17.jar
  D  lib/slf4j-api-1.6.6.jar
  A  lib/slf4j-api-1.7.2.jar
  A  lib/slf4j-log4j12-1.7.2.jar
  M  src/com/github/mattficken/io/ByteArrayIOStream.java
  M  src/com/mostc/pftt/host/ExecOutput.java
  M  src/com/mostc/pftt/host/Host.java
  M  src/com/mostc/pftt/host/SSHHost.java
  A  src/com/mostc/pftt/host/TempFileExecOutput.java
  M  src/com/mostc/pftt/main/PfttMain.java
  M  src/com/mostc/pftt/main/SSHServer.java
  M  src/com/mostc/pftt/model/phpt/PhpBuild.java
  M  src/com/mostc/pftt/model/phpt/PhpIni.java
  M  src/com/mostc/pftt/model/phpt/PhptTestCase.java
  M  src/com/mostc/pftt/model/smoke/RequiredExtensionsSmokeTest.java
  M  src/com/mostc/pftt/model/smoke/RequiredFeaturesSmokeTest.java
  M  src/com/mostc/pftt/model/ui/wordpress.groovy
  M  src/com/mostc/pftt/results/PhptResultPack.java
  M  src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java
  M  src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java
  M  src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
  M  src/com/mostc/pftt/runner/HttpTestCaseRunner.java
  M  src/com/mostc/pftt/scenario/AbstractParallelScenario.java
  M  src/com/mostc/pftt/scenario/AbstractSAPIScenario.java
  M  src/com/mostc/pftt/scenario/AbstractSMBScenario.java
  M  src/com/mostc/pftt/scenario/AbstractWebServerScenario.java
  M  src/com/mostc/pftt/scenario/CLIScenario.java
  M  src/com/mostc/pftt/scenario/NoCodeCacheScenario.java
  M  src/com/mostc/pftt/scenario/NoDebugScenario.java
  M  src/com/mostc/pftt/scenario/PlainSocketScenario.java
  M  src/com/mostc/pftt/scenario/SMBBasicScenario.java
  M  src/com/mostc/pftt/scenario/SMBCAScenario.java
  M  src/com/mostc/pftt/scenario/SMBDFSRScenario.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/ui/PhptHostTab.java
  M  src/com/mostc/pftt/util/StringUtil.java
  M  src/org/apache/sshd/server/filesystem/NativeSshFile.java

diff --git a/.classpath b/.classpath
index 0df8458..790b3df 100644
--- a/.classpath
+++ b/.classpath
@@ -21,7 +21,6 @@
        <classpathentry kind="lib" path="lib/asm-tree-3.2.jar"/>
        <classpathentry kind="lib" path="lib/asm-util-3.2.jar"/>
        <classpathentry kind="lib" path="lib/winp-1.14.jar"/>
-       <classpathentry kind="lib" path="lib/SSHD_fat.jar"/>
        <classpathentry kind="lib" path="lib/commons-net-3.1.jar"/>
        <classpathentry kind="lib" path="lib/commons-codec-1.6.jar"/>
        <classpathentry kind="lib" path="lib/commons-lang-2.6.jar"/>
@@ -29,6 +28,8 @@
        <classpathentry kind="lib" path="lib/jzlib-1.1.1.jar"/>
        <classpathentry kind="lib" path="lib/mina-core-2.0.7.jar"/>
        <classpathentry kind="lib" path="lib/mina-statemachine-2.0.7.jar"/>
-       <classpathentry kind="lib" path="lib/slf4j-api-1.6.6.jar"/>
+       <classpathentry kind="lib" path="lib/slf4j-api-1.7.2.jar"/>
+       <classpathentry kind="lib" path="lib/slf4j-log4j12-1.7.2.jar"/>
+       <classpathentry kind="lib" path="lib/log4j-1.2.17.jar"/>
        <classpathentry kind="output" path="build"/>
 </classpath>
diff --git a/bin/SetACL.exe b/bin/SetACL.exe
new file mode 100644
index 0000000..0ac0dfb
Binary files /dev/null and b/bin/SetACL.exe differ
diff --git a/bin/pftt.cmd b/bin/pftt.cmd
index cb97260..43b77d2 100644
--- a/bin/pftt.cmd
+++ b/bin/pftt.cmd
@@ -5,7 +5,7 @@ REM set important env vars
 CALL set_env
 SET PFTT_LIB=%PFTT_HOME%\lib
 
-SET 
CLASSPATH=%PFTT_HOME%\build;%PFTT_LIB%\winp-1.14.jar;%PFTT_LIB%\htmlcleaner-2.2.jar;%PFTT_LIB%\groovy-1.8.6.jar;%PFTT_LIB%\icu4j-49_1.jar;%PFTT_LIB%\icudata.jar;%PFTT_LIB%\icutzdata.jar;%PFTT_LIB%\j2ssh-common-0.2.9.jar;%PFTT_LIB%\j2ssh-core-0.2.9.jar;%PFTT_LIB%\jansi-1.7.jar;%PFTT_LIB%\jline-0.9.94.jar;%PFTT_LIB%\jzlib-1.0.7.jar;%PFTT_LIB%\selenium-server-standalone-2.19.0.jar;%PFTT_LIB%\xercesImpl.jar;%PFTT_LIB%\xmlpull-1.1.3.1.jar;%PFTT_LIB%\commons-net-3.1.jar;%PFTT_LIB%\commons-cli-1.2.jar;%PFTT_LIB%\antlr-2.7.7.jar;%PFTT_LIB%\asm-3.2.jar;%PFTT_LIB%\asm-analysis-3.2.jar;%PFTT_LIB%\asm-commons-3.2.jar;%PFTT_LIB%\asm-tree-3.2.jar;%PFTT_LIB%\asm-util-3.2.jar
+SET 
CLASSPATH=%PFTT_HOME%\build;%PFTT_LIB%\htmlcleaner-2.2.jar;%PFTT_LIB%\groovy-1.8.6.jar;%PFTT_LIB%\icu4j-49_1.jar;%PFTT_LIB%\icudata.jar;%PFTT_LIB%\icutzdata.jar;%PFTT_LIB%\jansi-1.7.jar;%PFTT_LIB%\jline-0.9.94.jar;%PFTT_LIB%\selenium-server-standalone-2.19.0.jar;%PFTT_LIB%\xercesImpl.jar;%PFTT_LIB%\xmlpull-1.1.3.1.jar;%PFTT_LIB%\commons-cli-1.2.jar;%PFTT_LIB%\antlr-2.7.7.jar;%PFTT_LIB%\asm-3.2.jar;%PFTT_LIB%\asm-analysis-3.2.jar;%PFTT_LIB%\asm-commons-3.2.jar;%PFTT_LIB%\asm-tree-3.2.jar;%PFTT_LIB%\asm-util-3.2.jar;%PFTT_LIB%\winp-1.14.jar;%PFTT_LIB%\commons-net-3.1.jar;%PFTT_LIB%\commons-codec-1.6.jar;%PFTT_LIB%\commons-lang-2.6.jar;%PFTT_LIB%\commons-logging-1.1.1.jar;%PFTT_LIB%\jzlib-1.1.1.jar;%PFTT_LIB%\mina-core-2.0.7.jar;%PFTT_LIB%\mina-statemachine-2.0.7.jar;%PFTT_LIB%\slf4j-api-1.7.2.jar;%PFTT_LIB%\slf4j-log4j12-1.7.2.jar
 
 
 REM if user added -uac or -auto or -windebug console options, run elevated in 
UAC
diff --git a/bin/ssh_server.cmd b/bin/ssh_server.cmd
new file mode 100644
index 0000000..34508ad
--- /dev/null
+++ b/bin/ssh_server.cmd
@@ -0,0 +1,62 @@
+@ECHO off
+REM script for running SSH Server on Windows
+
+CALL set_env
+SET PFTT_LIB=%PFTT_HOME%\lib
+
+SET 
CLASSPATH=%PFTT_HOME%\build;%PFTT_LIB%\commons-cli-1.2.jar;%PFTT_LIB%\winp-1.14.jar;%PFTT_LIB%\commons-net-3.1.jar;%PFTT_LIB%\commons-codec-1.6.jar;%PFTT_LIB%\commons-lang-2.6.jar;%PFTT_LIB%\commons-logging-1.1.1.jar;%PFTT_LIB%\jzlib-1.1.1.jar;%PFTT_LIB%\mina-core-2.0.7.jar;%PFTT_LIB%\mina-statemachine-2.0.7.jar;%PFTT_LIB%\slf4j-api-1.7.2.jar;%PFTT_LIB%\slf4j-log4j12-1.7.2.jar
+
+
+:run_it
+
+
+REM find java.exe
+IF [%JAVA_EXE%] == [] (
+       IF EXIST "%JAVA_HOME%\lib\tools.jar" (
+               SET JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+       ) ELSE (
+               IF [%JAVA_EXE%] == [] ( 
+                       IF EXIST "%ProgramFiles%\java\jre6\bin\java.exe" (
+                               SET 
JAVA_EXE="%ProgramFiles%\java\jre6\bin\java.exe"
+                               SET JAVA_HOME="%ProgramFiles%\java\jre6"
+                       ) ELSE (
+                               IF EXIST 
"%ProgramFiles(x86)%\java\jre6\bin\java.exe" (
+                                       SET 
JAVA_EXE="%ProgramFiles(x86)%\java\jre6\bin\java.exe"
+                                       SET 
JAVA_HOME="%ProgramFiles(x86)%\java\jre6"
+                               ) ELSE (
+                                       IF EXIST 
"%ProgramFiles%\java\jre7\bin\java.exe" (
+                                               SET 
JAVA_EXE="%ProgramFiles%\java\jre7\bin\java.exe"
+                                               SET 
JAVA_HOME="%ProgramFiles%\java\jre7"
+                                       ) ELSE (
+                                               IF EXIST 
"%ProgramFiles(x86)%\java\jre7\bin\java.exe" (
+                                                       SET 
JAVA_EXE="%ProgramFiles(x86)%\java\jre7\bin\java.exe"
+                                                       SET 
JAVA_HOME="%ProgramFiles(x86)%\java\jre7"
+                                               )
+                                       )
+                               )
+                       )
+               )
+       )
+)
+       
+IF [%JAVA_EXE%] == [] (
+       REM check PATH last. it might find java.exe in \Windows\System32\java
+       REM which elevate.exe can't find/execute for some weird reason
+       WHERE java > pftt_cmd.tmp
+       
+       IF %ERRORLEVEL% EQU 0 (
+               REM found java.exe in PATH
+               SET /p JAVA_EXE= < pftt_cmd.tmp
+       ) ELSE (
+               REM can't find java jre
+               ECHO java may not be installed. Must Install Sun Java JRE 6 or 
7.
+               ECHO user error set JAVA_HOME or add java to PATH and try again
+               DEL /Q pftt_cmd.tmp
+               EXIT /B 200
+       ) 
+       
+       DEL /Q pftt_cmd.tmp
+)
+
+REM finally execute
+%ELEVATOR% %JAVA_EXE% -classpath %CLASSPATH% com.mostc.pftt.main.SSHServer %*
diff --git a/lib/SSHD_fat.jar b/lib/SSHD_fat.jar
deleted file mode 100644
index 5224f2a..0000000
Binary files a/lib/SSHD_fat.jar and /dev/null differ
diff --git a/lib/log4j-1.2.17.jar b/lib/log4j-1.2.17.jar
new file mode 100644
index 0000000..068867e
Binary files /dev/null and b/lib/log4j-1.2.17.jar differ
diff --git a/lib/slf4j-api-1.6.6.jar b/lib/slf4j-api-1.6.6.jar
deleted file mode 100644
index 4c03fa6..0000000
Binary files a/lib/slf4j-api-1.6.6.jar and /dev/null differ
diff --git a/lib/slf4j-api-1.7.2.jar b/lib/slf4j-api-1.7.2.jar
new file mode 100644
index 0000000..73f38db
Binary files /dev/null and b/lib/slf4j-api-1.7.2.jar differ
diff --git a/lib/slf4j-log4j12-1.7.2.jar b/lib/slf4j-log4j12-1.7.2.jar
new file mode 100644
index 0000000..37a85d7
Binary files /dev/null and b/lib/slf4j-log4j12-1.7.2.jar differ
diff --git a/src/com/github/mattficken/io/ByteArrayIOStream.java 
b/src/com/github/mattficken/io/ByteArrayIOStream.java
index 73f8df8..476306a 100644
--- a/src/com/github/mattficken/io/ByteArrayIOStream.java
+++ b/src/com/github/mattficken/io/ByteArrayIOStream.java
@@ -29,6 +29,11 @@ public class ByteArrayIOStream extends OutputStream {
                return new ByteArrayInStream();
        }
        
+       @Override
+       public String toString() {
+               return new String(buf, 0, count);
+       }
+       
        public class ByteArrayInStream extends InputStream {
                protected int pos;
 
diff --git a/src/com/mostc/pftt/host/ExecOutput.java 
b/src/com/mostc/pftt/host/ExecOutput.java
index e31a9a4..e571454 100644
--- a/src/com/mostc/pftt/host/ExecOutput.java
+++ b/src/com/mostc/pftt/host/ExecOutput.java
@@ -48,8 +48,13 @@ public class ExecOutput {
                return printOutputIfCrash(ctx.getSimpleName(), ps);
        }
        public ExecOutput printOutputIfCrash(String ctx, PrintStream ps) {
-               if (ps!=null && isCrashed())
-                       ps.println(ctx+": "+output.trim());
+               if (ps!=null && isCrashed()) {
+                       String output_str = output.trim();
+                       if (StringUtil.isEmpty(output_str))
+                               output_str = "<Crash with no output. 
exit_code="+exit_code+">";
+                       
+                       ps.println(ctx+": "+output_str);
+               }
                return this;
        }
 } // end public class ExecOutput
diff --git a/src/com/mostc/pftt/host/Host.java 
b/src/com/mostc/pftt/host/Host.java
index 9aa99c0..b56b485 100644
--- a/src/com/mostc/pftt/host/Host.java
+++ b/src/com/mostc/pftt/host/Host.java
@@ -448,10 +448,19 @@ public abstract class Host {
        public ExecOutput execElevated(String cmd, int timeout_sec, Map<String, 
String> env, byte[] stdin_data, Charset charset, String chdir) throws Exception 
{
                return execElevated(cmd, timeout_sec, env, stdin_data, charset, 
chdir, null, FOUR_HOURS);
        }
+       private boolean checked_elevate, found_elevate;
        public ExecOutput execElevated(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())
-                       // execute command with this utility that will elevate 
the program using Windows UAC
-                       cmd = getPfttDir() + "\\bin\\elevate "+cmd;
+               if (isWindows()) {
+                       if (!checked_elevate) {
+                               found_elevate = 
exists(getPfttDir()+"\\bin\\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;
+                       }
+               }
                
                return exec(cmd, timeout_sec, env, stdin_data, charset, chdir, 
test_thread, slow_timeout_sec);
        }
@@ -802,6 +811,7 @@ public abstract class Host {
                if (!isWindows())
                        return false;
                String os_name = getOSNameOnWindows();
+               System.out.println(os_name);
                return os_name.contains("Windows 8") || 
os_name.contains("Windows 2012") || os_name.contains("Windows 9") || 
os_name.contains("Windows 2014");
        }
        
@@ -972,4 +982,38 @@ public abstract class Host {
                }
        }
        
+       /** executes Powershell code and returns output.
+        * 
+        * Takes care of making a temporary file, storing the powershell code, 
executing it, then cleaning up.
+        * 
+        * @param ctx
+        * @param cm
+        * @param ps_code - powershell code to execute (not filename)
+        * @param timeout - max time to allow powershell to run
+        * @return
+        * @throws Exception
+        */
+       public TempFileExecOutput powershell(Class<?> ctx, ConsoleManager cm, 
CharSequence ps_code, int timeout) throws Exception {
+               return powershell(ctx==null?null:ctx.getSimpleName(), cm, 
ps_code, timeout);
+       }
+       
+       private boolean set_unrestricted;
+       public TempFileExecOutput powershell(String ctx_str, ConsoleManager cm, 
CharSequence ps_code, int timeout) throws Exception {
+               if (!isWindows())
+                       throw new IllegalStateException("powershell is only 
supported on Windows");
+               
+               if (!set_unrestricted) {
+                       // do this once
+                       execElevated("powershell -Command \"set-executionpolicy 
unrestricted\"", Host.ONE_MINUTE).printOutputIfCrash(ctx_str, cm);
+                       
+                       set_unrestricted = true;
+               }
+               
+               String temp_file = mktempname(ctx_str, ".ps1");
+               
+               saveTextFile(temp_file, ps_code.toString());
+               
+               return new TempFileExecOutput(temp_file, 
execElevated("Powershell -File "+temp_file, timeout));
+       }
+       
 } // end public abstract class Host
diff --git a/src/com/mostc/pftt/host/SSHHost.java 
b/src/com/mostc/pftt/host/SSHHost.java
index d38213a..04dd4bb 100644
--- a/src/com/mostc/pftt/host/SSHHost.java
+++ b/src/com/mostc/pftt/host/SSHHost.java
@@ -1,6 +1,5 @@
 package com.mostc.pftt.host;
 
-import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -17,26 +16,23 @@ import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetEncoder;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import com.github.mattficken.io.AbstractDetectingCharsetReader;
+import javax.annotation.Nullable;
+
 import com.github.mattficken.io.ByLineReader;
 import com.github.mattficken.io.ByteArrayIOStream;
 import com.github.mattficken.io.CharsetByLineReader;
 import com.github.mattficken.io.CharsetDeciderDecoder;
-import com.github.mattficken.io.DefaultCharsetDeciderDecoder;
 import com.github.mattficken.io.IOUtil;
 import com.github.mattficken.io.MultiCharsetByLineReader;
 import com.github.mattficken.io.NoCharsetByLineReader;
-import com.mostc.pftt.model.phpt.PhptTestCase;
 import com.mostc.pftt.runner.AbstractTestPackRunner.TestPackRunnerThread;
 import com.mostc.pftt.util.StringUtil;
-import com.sshtools.j2ssh.ScpClient;
 import com.sshtools.j2ssh.SftpClient;
 import com.sshtools.j2ssh.SshClient;
 import com.sshtools.j2ssh.authentication.AuthenticationProtocolState;
@@ -78,7 +74,9 @@ import com.sshtools.j2ssh.transport.publickey.SshPublicKey;
  * -OpenSSH on Linux
  * -Apache Mina-SSH on Windows
  * 
- * SSH Server must support SESSION, SFTP and SCP channels (most do).
+ * SSH Server must support SESSION and SFTP channels (SCP channel not required)
+ * 
+ * NOTE: added 1 line to SftpClient#resolveRemotePath to support checking for 
[letter]:\ on Windows
  * 
  * @author Matt Ficken
  * 
@@ -86,13 +84,18 @@ import com.sshtools.j2ssh.transport.publickey.SshPublicKey;
 
 public class SSHHost extends RemoteHost {
        private static final Timer timer = new Timer();
-       protected final String hostname, username, password;
+       protected String address, hostname;
+       protected final String username, password;
        protected final int port;
+       protected final HostKeyVerification verif;
        protected boolean closed, login_fail;
-       protected String address, os_name_long;
+       @Nullable
+       protected String os_name_long;
+       @Nullable
        protected Boolean is_windows;
+       @Nullable
        protected SshClient ssh;
-       protected ScpClient scp;
+       @Nullable
        protected SftpClient sftp;
        
        public SSHHost(String hostname, String username, String password) {
@@ -100,11 +103,32 @@ public class SSHHost extends RemoteHost {
        }
        
        public SSHHost(String hostname, int port, String username, String 
password) {
+               this(hostname, port, username, password, new 
HostKeyVerification() {
+                               @Override
+                               public boolean verifyHost(String host, 
SshPublicKey pk) throws TransportProtocolException {
+                                       return true;
+                               }
+                       });
+       }
+       
+       public SSHHost(String hostname, String username, String password, 
HostKeyVerification verif) {
+               this(hostname, 22, username, password, verif);
+       }
+       
+       public SSHHost(String hostname, int port, String username, String 
password, HostKeyVerification verif) {
+               this.address = hostname;
+               
+               if (hostname.contains(".")||hostname.contains(":")) {
+                       // use address instead, then ask actual hostname once 
connected
+                       // @see #ensureSshOpen
+                       hostname = null;
+               }
+               
                this.hostname = hostname;
                this.port = port;
                this.username = username;
                this.password = password;
-               this.address = hostname;
+               this.verif = verif;
        }
        
        protected String normalizePath(String path) {
@@ -120,16 +144,13 @@ public class SSHHost extends RemoteHost {
                        throw new IllegalStateException("SSH connection 
administratively/explicitly closed");
                do_close(); // ensure any existing ssh, sftp or scp client gets 
closed (for gc)
                
-               address = InetAddress.getByName(hostname).getHostAddress();
-               
+               if (hostname!=null) {
+                       // address isn't IP address (its hostname), resolve it 
now @see SSHHost#<init>
+                       address = 
InetAddress.getByName(hostname).getHostAddress();
+               }
                ssh = new SshClient();
                
-               ssh.connect(address, port, new HostKeyVerification() {
-                               @Override
-                               public boolean verifyHost(String host, 
SshPublicKey pk) throws TransportProtocolException {
-                                       return true;
-                               }
-                       });
+               ssh.connect(address, port, verif);
                
                PasswordAuthenticationClient pwd = new 
PasswordAuthenticationClient();
 
@@ -141,14 +162,12 @@ public class SSHHost extends RemoteHost {
                        login_fail = true; // IllegalStateException below may 
get caught/ignored
                        throw new IllegalStateException("authentication failed. 
attempted login as user: "+username+" using password: "+password+" on host: 
"+hostname+":"+port+" ("+address+":"+port+")");
                }
-       }
-       
-       protected void ensureScpOpen() throws UnknownHostException, IOException 
{
-               if (!login_fail && scp != null)
-                       return;
-               ensureSshOpen();
-               scp = ssh.openScpClient();
-       }
+               
+               if (hostname==null) {
+                       // only have ip address, get hostname
+                       hostname = isWindows() ? getEnvValue("COMPUTERNAME") : 
getEnvValue("HOSTNAME");
+               }
+       } // end protected void ensureSshOpen
        
        protected void ensureSftpOpen() throws UnknownHostException, 
IOException {
                if (!login_fail && sftp != null && !sftp.isClosed())
@@ -176,7 +195,6 @@ public class SSHHost extends RemoteHost {
                        }
                        sftp = null;
                }
-               scp = null;
                if (ssh!=null) {
                        ssh.disconnect();
                        ssh = null;
@@ -227,7 +245,8 @@ public class SSHHost extends RemoteHost {
                        FileAttributes fa = sftp.stat(normalizePath(path));
                        return fa.isFile() || fa.isDirectory();
                } catch ( Exception ex ) {
-                       ex.printStackTrace();
+                       // throws Exception if it doesn't exist
+                       //ex.printStackTrace();
                }
                return false;
        }
@@ -262,8 +281,10 @@ public class SSHHost extends RemoteHost {
 
        @Override
        public String getContents(String file) throws IOException {
-               ensureScpOpen();
-               NoCharsetByLineReader reader = new 
NoCharsetByLineReader(scp.get(normalizePath(file)));
+               ensureSftpOpen();
+               ByteArrayIOStream local = new ByteArrayIOStream(1024);
+               sftp.get(normalizePath(file), local);
+               NoCharsetByLineReader reader = new 
NoCharsetByLineReader(local.getInputStream());
                String str = IOUtil.toString(reader, IOUtil.HALF_MEGABYTE);
                reader.close();
                return str;
@@ -271,8 +292,10 @@ public class SSHHost extends RemoteHost {
 
        @Override
        public String getContentsDetectCharset(String file, 
CharsetDeciderDecoder cdd) throws IOException {
-               ensureScpOpen();
-               MultiCharsetByLineReader reader = new 
MultiCharsetByLineReader(scp.get(normalizePath(file)), cdd);
+               ensureSftpOpen();
+               ByteArrayIOStream local = new ByteArrayIOStream(1024);
+               sftp.get(normalizePath(file), local);
+               MultiCharsetByLineReader reader = new 
MultiCharsetByLineReader(local.getInputStream(), cdd);
                String str = IOUtil.toString(reader, IOUtil.HALF_MEGABYTE);
                reader.close();
                return str;
@@ -280,14 +303,18 @@ public class SSHHost extends RemoteHost {
 
        @Override
        public ByLineReader readFile(String file) throws FileNotFoundException, 
IOException {
-               ensureScpOpen();
-               return new NoCharsetByLineReader(scp.get(normalizePath(file)));
+               ensureSftpOpen();
+               ByteArrayIOStream local = new ByteArrayIOStream(1024);
+               sftp.get(normalizePath(file), local);
+               return new NoCharsetByLineReader(local.getInputStream());
        }
 
        @Override
        public ByLineReader readFileDetectCharset(String file, 
CharsetDeciderDecoder cdd) throws FileNotFoundException, IOException {
-               ensureScpOpen();
-               return new 
MultiCharsetByLineReader(scp.get(normalizePath(file)), cdd);
+               ensureSftpOpen();
+               ByteArrayIOStream local = new ByteArrayIOStream(1024);
+               sftp.get(normalizePath(file), local);
+               return new MultiCharsetByLineReader(local.getInputStream(), 
cdd);
        }
 
        @Override
@@ -385,7 +412,7 @@ public class SSHHost extends RemoteHost {
                //
                final AtomicBoolean run = new AtomicBoolean(true);
                final SessionChannelClient session = do_exec(cmd, env, chdir, 
stdin_post, out);
-               if (timeout>FOUR_HOURS) {
+               if (timeout>NO_TIMEOUT) {
                        timer.schedule(new TimerTask() {
                                        public void run() {
                                                try {
@@ -408,7 +435,7 @@ public class SSHHost extends RemoteHost {
                //
                
                // read output from command
-               StringBuilder sb = new StringBuilder(1024);
+               /* TODO StringBuilder sb = new StringBuilder(1024);
                DefaultCharsetDeciderDecoder d = charset == null ? null : 
PhptTestCase.newCharsetDeciderDecoder();
                ByLineReader reader = charset == null ? new 
NoCharsetByLineReader(out.getInputStream()) : new 
MultiCharsetByLineReader(out.getInputStream(), d);
                String line;
@@ -424,16 +451,16 @@ public class SSHHost extends RemoteHost {
                        //ex.printStackTrace();
                }
                
-               out.close();
+               out.close();*/
                
                // wait for exit
                session.getState().waitForState(ChannelState.CHANNEL_CLOSED);
                
                //
                eo.exit_code = session.getExitCode();
-               if (reader instanceof AbstractDetectingCharsetReader)
-                       eo.charset = 
((AbstractDetectingCharsetReader)reader).cs;
-               eo.output = sb.toString();
+               /* TODO if (reader instanceof AbstractDetectingCharsetReader)
+                       eo.charset = 
((AbstractDetectingCharsetReader)reader).cs; */
+               eo.output = out.toString();
                //
                
                return eo;
@@ -458,7 +485,7 @@ public class SSHHost extends RemoteHost {
        public String getEnvValue(String name) {
                try {
                        if (isWindows())
-                               return cmd("ECHO %"+name+"%", 
ONE_MINUTE).output;
+                               return StringUtil.chomp(cmd("ECHO %"+name+"%", 
ONE_MINUTE).output);
                        else
                                return exec("echo $"+name, ONE_MINUTE).output;
                } catch ( Exception ex ) {
@@ -492,34 +519,33 @@ public class SSHHost extends RemoteHost {
 
        @Override
        public void download(String src, String dst) throws 
IllegalStateException, IOException, Exception {
-               ensureScpOpen();
-               IOUtil.copy(scp.get(normalizePath(src)), new 
BufferedOutputStream(new FileOutputStream(dst)), IOUtil.HALF_MEGABYTE);
+               ensureSftpOpen();
+               sftp.get(normalizePath(src), new BufferedOutputStream(new 
FileOutputStream(dst)));
        }
        
-       protected static void walk(File[] files, LinkedList<String> file_list) {
+       protected void do_upload(String base, File[] files, String dst) throws 
IOException {
                for (File file : files) {
-                       if (file.isDirectory())
-                               walk(file.listFiles(), file_list);
-                       else
-                               file_list.add(file.getAbsolutePath());
+                       if (file.isDirectory()) {
+                               do_upload(base, file.listFiles(), dst);
+                       } else {
+                               String remote_file_path = joinIntoOnePath(dst, 
pathFrom(base, file.getAbsolutePath()));
+                               
+                               sftp.put(file.getAbsolutePath(), 
remote_file_path);
+                       }
                }
        }
 
        @Override
-       public void upload(String src, String dst) throws 
IllegalStateException, IOException, Exception {
-               ensureScpOpen();
+       public void upload(String src, String dst) throws 
IllegalStateException, IOException {
+               ensureSftpOpen();
                dst = normalizePath(dst);
                
                File fsrc = new File(src);
                if (fsrc.isDirectory()) {
-                       LinkedList<String> file_list = new LinkedList<String>();
-                       
-                       walk(fsrc.listFiles(), file_list);
-                       
-                       scp.put((String[]) file_list.toArray(new 
String[file_list.size()]), dst, false);
+                       do_upload(src, fsrc.listFiles(), dst);
                } else {
                        // uploading single file
-                       scp.put(new BufferedInputStream(new 
FileInputStream(fsrc)), fsrc.length(), src, dst);
+                       sftp.put(fsrc.getAbsolutePath(), dst);
                }
        }
 
@@ -636,16 +662,16 @@ public class SSHHost extends RemoteHost {
        public void saveTextFile(String filename, String text, CharsetEncoder 
ce) throws IllegalStateException, IOException {
                if (text==null)
                        text = "";
-               ensureScpOpen();
+               ensureSftpOpen();
                filename = normalizePath(filename);
                
                if (ce==null) {
                        byte[] text_bytes = text.getBytes();
-                       scp.put(new ByteArrayInputStream(text_bytes), 
text_bytes.length, filename, filename);
+                       sftp.put(new ByteArrayInputStream(text_bytes), 
filename);
                } else {
                        ByteBuffer bbuf = 
ByteBuffer.allocate(50+text.length()*2);
                        ce.encode(CharBuffer.wrap(text.toCharArray()), bbuf, 
true);
-                       scp.put(new ByteBufferInputStream(bbuf), 
bbuf.capacity() - bbuf.remaining(), filename, filename);
+                       sftp.put(new ByteBufferInputStream(bbuf), filename);
                }
        }
        
diff --git a/src/com/mostc/pftt/host/TempFileExecOutput.java 
b/src/com/mostc/pftt/host/TempFileExecOutput.java
new file mode 100644
index 0000000..33b8218
--- /dev/null
+++ b/src/com/mostc/pftt/host/TempFileExecOutput.java
@@ -0,0 +1,31 @@
+package com.mostc.pftt.host;
+
+public class TempFileExecOutput extends ExecOutput {
+       public String temp_file;
+       
+       public TempFileExecOutput() {
+               
+       }
+       
+       public TempFileExecOutput(String temp_file, ExecOutput eo) {
+               this.charset = eo.charset;
+               this.exit_code = eo.exit_code;
+               this.output = eo.output;
+               this.temp_file = temp_file;
+       }
+
+       public boolean cleanupIfSuccess(Host host) {
+               if (isSuccess()) {
+                       cleanup(host);
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+       
+       public void cleanup(Host host) {
+               try {
+                       host.delete(temp_file);
+               } catch ( Exception ex ) {}
+       }
+}
diff --git a/src/com/mostc/pftt/main/PfttMain.java 
b/src/com/mostc/pftt/main/PfttMain.java
index 3bdb785..94b8987 100644
--- a/src/com/mostc/pftt/main/PfttMain.java
+++ b/src/com/mostc/pftt/main/PfttMain.java
@@ -22,6 +22,7 @@ import org.codehaus.groovy.tools.shell.IO;
 import com.mostc.pftt.host.ExecOutput;
 import com.mostc.pftt.host.Host;
 import com.mostc.pftt.host.LocalHost;
+import com.mostc.pftt.host.SSHHost;
 import com.mostc.pftt.model.app.PhpUnitAppTestPack;
 import com.mostc.pftt.model.phpt.EBuildBranch;
 import com.mostc.pftt.model.phpt.EBuildType;
@@ -45,6 +46,8 @@ import com.mostc.pftt.runner.PhpUnitTestPackRunner;
 import com.mostc.pftt.runner.LocalPhptTestPackRunner;
 import com.mostc.pftt.runner.PhptTestPackRunner;
 import com.mostc.pftt.scenario.AbstractSAPIScenario;
+import com.mostc.pftt.scenario.SMBDFSRScenario;
+import com.mostc.pftt.scenario.SMBDeduplicationScenario;
 import com.mostc.pftt.scenario.Scenario;
 import com.mostc.pftt.scenario.ScenarioSet;
 import com.mostc.pftt.util.DownloadUtil;
@@ -571,7 +574,7 @@ public class PfttMain {
                int args_i = 0;
                
                Config config = null;
-               boolean is_uac = false, windebug = false, pftt_debug = false, 
show_gui = false, force = false, disable_debug_prompt = true, results_only = 
false, dont_cleanup_test_pack = false, phpt_not_in_place = false;
+               boolean is_uac = false, windebug = false, pftt_debug = false, 
show_gui = false, force = false, disable_debug_prompt = false, results_only = 
false, dont_cleanup_test_pack = false, phpt_not_in_place = false;
                String source_pack = null;
                PhpDebugPack debug_pack = null;
                LinkedList<File> config_files = new LinkedList<File>();
@@ -720,6 +723,23 @@ public class PfttMain {
                
                LocalConsoleManager cm = new LocalConsoleManager(source_pack, 
debug_pack, force, windebug, results_only, show_gui, disable_debug_prompt, 
dont_cleanup_test_pack, phpt_not_in_place, pftt_debug);
                
+               // TODO 
+               /*
+               SSHHost remote_host = new SSHHost("10.200.41.219", 
"administrator", "password01!");
+               System.out.println(remote_host.isWindows());
+               System.out.println("729");
+               remote_host.exec("systeminfo", Host.ONE_MINUTE);
+               System.out.println("731");
+               //SMBDeduplicationScenario d = new 
SMBDeduplicationScenario(remote_host, "F:");
+               SMBDFSRScenario d = new SMBDFSRScenario(remote_host);
+               System.out.println("731");
+               System.out.println(d.notifyPrepareStorageDir(cm, rt.host));
+               d.notifyTestPackInstalled(cm, rt.host);
+               
+               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);
@@ -853,7 +873,7 @@ public class PfttMain {
                                checkUAC(is_uac, false, config, cm);
                                
                                // run all tests
-                               HostEnvUtil.prepareHostEnv(rt.host, cm, 
!!cm.isDisableDebugPrompt());
+                               HostEnvUtil.prepareHostEnv(rt.host, cm, 
!cm.isDisableDebugPrompt());
                                cmd_phpt_all(rt, cm, config, build, test_pack);
                                
                                System.out.println("PFTT: finished");
diff --git a/src/com/mostc/pftt/main/SSHServer.java 
b/src/com/mostc/pftt/main/SSHServer.java
index a41154a..4639b8a 100644
--- a/src/com/mostc/pftt/main/SSHServer.java
+++ b/src/com/mostc/pftt/main/SSHServer.java
@@ -3,7 +3,10 @@ package com.mostc.pftt.main;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.EnumSet;
+import java.util.LinkedList;
+import java.util.regex.Pattern;
 
+import org.apache.log4j.BasicConfigurator;
 import org.apache.sshd.SshServer;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.server.Command;
@@ -14,52 +17,96 @@ import org.apache.sshd.server.session.ServerSession;
 import org.apache.sshd.server.sftp.SftpSubsystem;
 import org.apache.sshd.server.shell.ProcessShellFactory;
 
-import com.mostc.pftt.host.LocalHost;
+import com.mostc.pftt.util.StringUtil;
+
+// NOTE: modified NativeSshFile#getPhysicalName to check for [letter]:\ on 
Windows
+//       and NativeSshFile#<init>
 
 public class SSHServer {
-  public static void main(String[] args) throws IOException {
-    SshServer sshd = SshServer.setUpDefaultServer();
+       
+       public static void main(String[] args) throws IOException {
+               BasicConfigurator.configure();
+        
+               SshServer sshd = SshServer.setUpDefaultServer();
 
-    ArrayList<NamedFactory<Command>> f = new 
ArrayList<NamedFactory<Command>>(1);
-    f.add(new SftpSubsystem.Factory());
-    sshd.setSubsystemFactories(f);
+               ArrayList<NamedFactory<Command>> f = new 
ArrayList<NamedFactory<Command>>(1);
+               f.add(new SftpSubsystem.Factory());
+               sshd.setSubsystemFactories(f);
 
-    if (System.getProperty("os.name").contains("Windows"))
-      sshd.setShellFactory(psf("cmd.exe"));
-    else
-      sshd.setShellFactory(psf("bash"));
+               if (System.getProperty("os.name").contains("Windows"))
+                       sshd.setShellFactory(psf("cmd.exe"));
+               else
+                       sshd.setShellFactory(psf("bash"));
 
-    sshd.setCommandFactory(new CommandFactory() {
-             public Command createCommand(String command) {
-               return psf(command).create();
-             }
-           });
-    sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
-             public boolean authenticate(String username, String password, 
ServerSession session) {
-               return (username.equals("administrator")) && 
(password.equals("password01!"));
-             }
-           });
-    sshd.setPort(22);
-    sshd.setReuseAddress(true);
-    sshd.setKeyPairProvider(new 
SimpleGeneratorHostKeyProvider("hostkeys.txt"));
-    sshd.start();
-  }
+               sshd.setCommandFactory(new CommandFactory() {
+                       public Command createCommand(String command) {
+                               return psf(command).create();
+                       }
+               });
+               sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
+                       public boolean authenticate(String username, String 
password, ServerSession session) {
+                               return (username.equals("administrator")) && 
(password.equals("password01!"));
+                       }
+               });
+               sshd.setPort(22);
+               sshd.setReuseAddress(true);
+               sshd.setKeyPairProvider(new 
SimpleGeneratorHostKeyProvider("hostkeys.txt"));
+               sshd.start();
+       }
+       
+       public static String[] splitCmdString(String command) {
+               LinkedList<String> parts = new LinkedList<String>();
+               String buf = "";
+               char c;
+               boolean in_quote = false;
+               for ( int i=0 ; i < command.length() ; i++ ) {
+                       c = command.charAt(i);
+                       if (c=='\"' && (i==0||command.charAt(i-1) != '\\')) {
+                               in_quote = !in_quote;
+                       }
+                       if (c == ' ' && !in_quote) {
+                               buf = buf.trim();
+                               if (buf.length() > 0) {
+                                       buf = StringUtil.unquote(buf);
+                                       
+                                       buf = StringUtil.replaceAll(PAT_QUOTE, 
"\"", buf);
+                                       
+                                       parts.add(buf);
+                               }
+                               buf = "";
+                               continue;
+                       }
+                       buf += c;
+               }
+               buf = buf.trim();
+               if (buf.length() > 0) {
+                       if (buf.startsWith("\"")) {
+                               buf = buf.substring(1, buf.length()-1);
+                               
+                               buf = StringUtil.replaceAll(PAT_QUOTE, "\"", 
buf);
+                       }
+                       parts.add(buf);
+               }
+               
+               return (String[])parts.toArray(new String[]{});
+       } // end public static String[] splitCmdString
+       private static final Pattern PAT_QUOTE = Pattern.compile("\\\"");
+       
+       private static ProcessShellFactory psf(String command) {
+               String[] commands;
+               if (command.contains(" ")) {
+                       commands = splitCmdString(command);
+               } else {
+                       commands = new String[] { command };
+               }
 
-  private static ProcessShellFactory psf(String command) {
-    String[] commands;
-    if (command.contains(" ")) {
-      commands = LocalHost.splitCmdString(command);
-    } else
-      commands = new String[] { command };
-    
-    if (System.getProperty("os.name").contains("Windows")) {
+               if (System.getProperty("os.name").contains("Windows")) {
+                       return new ProcessShellFactory(
+                                       commands, 
+                                       
EnumSet.of(ProcessShellFactory.TtyOptions.Echo, 
ProcessShellFactory.TtyOptions.ICrNl, ProcessShellFactory.TtyOptions.ONlCr));
+               }
 
-      return new ProcessShellFactory(
-        commands, 
-        EnumSet.of(ProcessShellFactory.TtyOptions.Echo, 
ProcessShellFactory.TtyOptions.ICrNl, ProcessShellFactory.TtyOptions.ONlCr));
-    }
+               return new ProcessShellFactory(commands);
+       }
 
-    return new ProcessShellFactory(commands);
-  }
-  
 } // end public class SSHServer
diff --git a/src/com/mostc/pftt/model/phpt/PhpBuild.java 
b/src/com/mostc/pftt/model/phpt/PhpBuild.java
index 6fd2a06..74c731d 100644
--- a/src/com/mostc/pftt/model/phpt/PhpBuild.java
+++ b/src/com/mostc/pftt/model/phpt/PhpBuild.java
@@ -11,7 +11,9 @@ import javax.annotation.Nullable;
 
 import com.mostc.pftt.host.ExecOutput;
 import com.mostc.pftt.host.Host;
+import com.mostc.pftt.host.TempFileExecOutput;
 import com.mostc.pftt.model.sapi.SAPIManager;
+import com.mostc.pftt.model.smoke.RequiredExtensionsSmokeTest;
 import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.ConsoleManager.EPrintType;
 import com.mostc.pftt.util.StringUtil;
@@ -306,7 +308,7 @@ public class PhpBuild extends SAPIManager {
                if (host.exists(path))
                        ini = new PhpIni(host.getContents(path), build_path);
                else
-                       ini = PhpIni.createDefaultIniCopy(host, this);
+                       ini = 
RequiredExtensionsSmokeTest.createDefaultIniCopy(host, this);
                
                this.php_ini = new WeakReference<PhpIni>(ini);
                return ini;
@@ -614,17 +616,13 @@ public class PhpBuild extends SAPIManager {
                return eval(host, null, code, timeout_seconds, auto_cleanup);
        }
        
-       public static class PHPOutput extends ExecOutput {
+       public static class PHPOutput extends TempFileExecOutput {
                /** the filename that the code was stored in for execution
                 * 
                 */
-               public String php_filename;
                
                protected PHPOutput(String php_filename, ExecOutput output) {
-                       this.charset = output.charset;
-                       this.exit_code = output.exit_code;
-                       this.output = output.output;
-                       this.php_filename = php_filename;
+                       super(php_filename, output);
                }
                
                public boolean hasFatalError() {
@@ -638,18 +636,17 @@ public class PhpBuild extends SAPIManager {
                }
                public PHPOutput printHasFatalError(String ctx, PrintStream ps) 
{
                        if (hasFatalError()) {
-                               ps.println(ctx+": "+output.trim());
+                               String output_str = output.trim();
+                               if (StringUtil.isEmpty(output_str))
+                                       output_str = "<PHP Crashed with no 
output. exit_code = "+exit_code+">";
+                               
+                               ps.println(ctx+": "+output_str);
                                return this;
                        } else {
                                return printOutputIfCrash(ctx, ps);
                        }
                }
                
-               public void cleanup(Host host) {
-                       try {
-                               host.delete(php_filename);
-                       } catch ( Exception ex ) {}
-               }
                @Override
                public PHPOutput printOutputIfCrash(String ctx, ConsoleManager 
cm) {
                        return (PHPOutput) super.printOutputIfCrash(ctx, cm);
@@ -706,7 +703,7 @@ public class PhpBuild extends SAPIManager {
         * @return
         */
        public String getDefaultExtensionDir() {
-               return build_path+"/ext";
+               return build_path.contains("/") ? build_path+"/ext" : 
build_path+"\\ext";
        }
        
 } // end public class PhpBuild
diff --git a/src/com/mostc/pftt/model/phpt/PhpIni.java 
b/src/com/mostc/pftt/model/phpt/PhpIni.java
index 515c67e..c464006 100644
--- a/src/com/mostc/pftt/model/phpt/PhpIni.java
+++ b/src/com/mostc/pftt/model/phpt/PhpIni.java
@@ -63,7 +63,7 @@ public class PhpIni {
        public static final String ISO_8859_1 = "ISO-8859-1";
        public static final String U_INVALID_SUBSTITUTE = 
"U_INVALID_SUBSTITUTE";
        public static final String DOT_HTML = ".html";
-       public static final String E_ALL_OR_E_STRICT = "E_ALL|E_STRICT";
+       public static final String E_ALL_NOTICE_WARNING = "E_ALL | E_NOTICE | 
E_WARNING";
        //
        private static String dllName(String name) {
                // FUTURE macos x and solaris support
@@ -97,94 +97,12 @@ public class PhpIni {
        public static final String EXT_TIDY = dllName("tidy");
        public static final String EXT_XMLRPC = dllName("xmlrpc");
        public static final String EXT_XSL = dllName("xsl");
-       public static PhpIni createDefaultIniCopy(Host host, PhpBuild build) {
-               PhpIni ini = new PhpIni();
-               ini.putSingle("default_mimetype", "text/plain");
-               ini.putMulti(OUTPUT_HANDLER, StringUtil.EMPTY);
-               ini.putMulti(OPEN_BASEDIR, StringUtil.EMPTY);
-               ini.putMulti(SAFE_MODE, 0);
-               ini.putMulti(DISABLE_DEFS, OFF);
-               ini.putMulti(OUTPUT_BUFFERING, ON);
-               ini.putMulti("engine", "On");
-               ini.putMulti("zend.enable_gc", "On");
-               ini.putMulti("expose_php ", "On");
-               //
-               // CRITICAL
-               ini.putMulti(ERROR_REPORTING, "E_ALL | E_NOTICE | E_WARNING"); 
// TODO E_ALL_OR_E_STRICT);
-               // CRITICAL
-               ini.putMulti(DISPLAY_ERRORS, "On");//1);
-               // CRITICAL
-               ini.putMulti(DISPLAY_STARTUP_ERRORS, "On");//0);
-               // CRITICAL
-               ini.putMulti(LOG_ERRORS, "On");//0);
-               // CRITICAL
-               ini.putMulti(HTML_ERRORS, "On");//0);
-               // CRITICAL
-               ini.putMulti(TRACK_ERRORS, "On");//1);
-               //
-               ini.putMulti(REPORT_MEMLEAKS, "On");
-               ini.putMulti(REPORT_ZEND_DEBUG, 0);
-               ini.putMulti(DOCREF_ROOT, StringUtil.EMPTY);
-               ini.putMulti(DOCREF_EXT, DOT_HTML);
-               ini.putMulti(ERROR_PREPEND_STRING, StringUtil.EMPTY);
-               ini.putMulti(ERROR_APPEND_STRING, StringUtil.EMPTY);
-               ini.putMulti(AUTO_PREPEND_FILE, StringUtil.EMPTY);
-               ini.putMulti(AUTO_APPEND_FILE, StringUtil.EMPTY);
-               ini.putMulti(MAGIC_QUOTES_RUNTIME, 0);
-               ini.putMulti(IGNORE_REPEATED_ERRORS, 0);
-               ini.putMulti(PRECISION, 14);
-               ini.putMulti(UNICODE_RUNTIME_ENCODING, ISO_8859_1);
-               ini.putMulti(UNICODE_SCRIPT_ENCODING, UTF_8);
-               ini.putMulti(UNICODE_OUTPUT_ENCODING, UTF_8);
-               ini.putMulti(UNICODE_FROM_ERROR_MODE, U_INVALID_SUBSTITUTE);
-               ini.putMulti(SESSION_AUTO_START, 0);
-               
-               // default php.ini has these extensions on Windows
-               // NOTE: this is validated by RequiredExtensionsSmokeTest. 
similar/same info is both there and here
-               //       b/c that needs it for validation and its here because 
its in the default php.ini
-               if (host.isWindows()) {
-                       ini.setExtensionDir(build.getDefaultExtensionDir());
-                       /*ini.addExtensions(
-                                       EXT_BZ2,
-                                       EXT_COM_DOTNET,
-                                       EXT_CURL,
-                                       EXT_FILEINFO,
-                                       EXT_GD2,
-                                       EXT_GETTEXT,
-                                       EXT_GMP,
-                                       EXT_INTL,
-                                       EXT_IMAP,
-                                       EXT_LDAP,
-                                       EXT_MBSTRING,
-                                       EXT_EXIF,
-                                       EXT_MYSQL,
-                                       EXT_MYSQLI,
-                                       EXT_OPENSSL,
-                                       EXT_PDO_MYSQL,
-                                       EXT_PDO_PGSQL,
-                                       EXT_PDO_SQLITE,
-                                       EXT_PDO_ODBC,
-                                       EXT_PGSQL,
-                                       EXT_SHMOP,
-                                       EXT_SOAP,
-                                       EXT_SOCKETS,
-                                       EXT_SQLITE3,
-                                       EXT_TIDY,
-                                       EXT_XMLRPC,
-                                       EXT_XSL
-                               );*/
-               }
-               
-               // TIMING: do this after all calls to #putMulti, etc... b/c 
that sets is_default = false
-               ini.is_default = true;
-               return ini;
-       } // end public static PhpIni createDefaultIniCopy
        //
        //
        private final HashMap<String, ArrayList<String>> ini_map;
        private WeakReference<PhpIni> ext_ini;
        private WeakReference<String> ini_str, cli_arg;
-       private boolean is_default = false;
+       public boolean is_default = false;
        
        public PhpIni() {
                ini_map = new HashMap<String, ArrayList<String>>();
@@ -216,15 +134,9 @@ public class PhpIni {
        public PhpIni(String ini_str, String pwd) {
                this();
                if (pwd!=null&&ini_str.contains("{PWD}")) {
-                       // TODO important to use \\\\
-                       if (pwd.contains("cache_list")) {
-                               
pwd="C:/php-sdk/php-test-pack-5.4-ts-windows-vc9-x86-r811cd76/ext/phar/tests/cache_list";
-                       }
-                       //pwd = 
"C:\\\\php-sdk\\\\php-test-pack-5.4-ts-windows-vc9-x86-r811cd76\\\\"; // TODO 
temp
                        ini_str = StringUtil.replaceAll(PAT_PWD, pwd, ini_str);
                        
-                       // BN: ensure that correct \\s are used for paths on 
Windows
-                       // TODO ini_str = StringUtil.replaceAll(PAT_FS, "\\\\", 
ini_str);
+                       // CRITICAL: ensure that correct \\s are used for paths 
on Windows
                }
                // read ini string, line by line
                for (String line : StringUtil.splitLines(ini_str)) {
diff --git a/src/com/mostc/pftt/model/phpt/PhptTestCase.java 
b/src/com/mostc/pftt/model/phpt/PhptTestCase.java
index adf22ef..4028047 100644
--- a/src/com/mostc/pftt/model/phpt/PhptTestCase.java
+++ b/src/com/mostc/pftt/model/phpt/PhptTestCase.java
@@ -64,28 +64,23 @@ public class PhptTestCase extends TestCase {
                        new String[]{"ext/standard/tests/file/symlink_"},
                        new 
String[]{"ext/standard/tests/file/file_get_contents_", 
"ext/standard/tests/file/file_put_contents_"},
                        new String[]{"ext/standard/tests/file/windows_acls/", 
"ext/standard/tests/file/windows_links/"},
-                       //new String[]{"ext/standard/tests/file/0"},
                        // note: this array is processed in order, so this 
entry will catch any remaining /file/ phpts
-                       //new String[]{"ext/standard/tests/file/"},
                        new String[]{"ext/standard/tests/dir/"},
-                       // TODO
                        new 
String[]{"ext/standard/tests/streams/stream_get_meta_data_socket_variation1.phpt"},
                        new 
String[]{"ext/standard/tests/streams/stream_get_meta_data_socket_variation2.phpt"},
                        new 
String[]{"ext/standard/tests/streams/stream_get_meta_data_socket_variation3.phpt"},
                        new 
String[]{"ext/standard/tests/streams/stream_get_meta_data_socket_variation4.phpt"},
                        new String[]{"ext/standard/tests/sockets/", 
"ext/sockets/"},
-                       // TODO new String[]{"tests/security/"},
                        // the bug38450* tests fail randomly under apache if 
run on apache instance
                        // with other tests - run them (serially) on their own 
apache instance
                        new String[]{"ext/standard/tests/file/bug38450"},
                        new String[]{"ext/standard/tests/network/"},
-                       // TODO new String[]{"ext/session", 
"tests/basic/bug20539.phpt"},
                        new String[]{"ext/mysql/", "ext/pdo_mysql/", 
"ext/mysqli/"},
                        new String[]{"ext/pgsql/", "ext/pdo_pgsql/"},
                        // several 61367 tests that aren't thread-safe (temp 
files)
                        new String[]{"ext/libxml/tests/bug61367"},
                        new String[]{"sapi/cli/tests/php_cli_server_"},
-                       // TODO new String[]{"sapi/cgi/"},
+                       new String[]{"ext/standard/tests/strings/vprintf_"},
                        new String[]{"ext/firebird/", "ext/pdo_firebird/"},
                        new String[]{"ext/sybase/"},
                        new String[]{"ext/interbase/", "ext/pdo_interbase/"},
@@ -725,7 +720,7 @@ public class PhptTestCase extends TestCase {
                ArrayList<String> test_names = new ArrayList<String>(2);
                
                if (!output.hasFatalError()) {
-                       String base_dir = Host.dirname(output.php_filename);
+                       String base_dir = Host.dirname(output.temp_file);
                        for (String line : output.getLines()) {
                                // code may use __DIR__ to get its current 
directory => strip off current directory(/tmp, etc...)
                                if (line.startsWith(base_dir)) {
@@ -737,6 +732,9 @@ public class PhptTestCase extends TestCase {
                                        continue;
                                test_names.add(line);
                        }
+                       
+                       // delete temporary file
+                       output.cleanup(host);
                }
                
                return test_names.toArray(new String[test_names.size()]);
diff --git a/src/com/mostc/pftt/model/smoke/RequiredExtensionsSmokeTest.java 
b/src/com/mostc/pftt/model/smoke/RequiredExtensionsSmokeTest.java
index bef7684..e54b116 100644
--- a/src/com/mostc/pftt/model/smoke/RequiredExtensionsSmokeTest.java
+++ b/src/com/mostc/pftt/model/smoke/RequiredExtensionsSmokeTest.java
@@ -3,8 +3,10 @@ package com.mostc.pftt.model.smoke;
 import com.mostc.pftt.host.Host;
 import com.mostc.pftt.model.phpt.ESAPIType;
 import com.mostc.pftt.model.phpt.PhpBuild;
+import com.mostc.pftt.model.phpt.PhpIni;
 import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.ConsoleManager.EPrintType;
+import com.mostc.pftt.util.StringUtil;
 
 /** Smoke test that verifies a PHP Build has all the required extensions.
  * 
@@ -103,5 +105,93 @@ public class RequiredExtensionsSmokeTest extends SmokeTest 
{
        public String getName() {
                return "Required-Extensions";
        }
+
+       /** creates a PhpIni with default configuration, default extensions 
loaded etc...
+        * 
+        * A PhpBuild using this PhpIni should pass this test.
+        * 
+        * @param host
+        * @param build
+        * @return
+        */
+       public static PhpIni createDefaultIniCopy(Host host, PhpBuild build) {
+               PhpIni ini = new PhpIni();
+               ini.putSingle("default_mimetype", "text/plain");
+               ini.putMulti(PhpIni.OUTPUT_HANDLER, StringUtil.EMPTY);
+               ini.putMulti(PhpIni.OPEN_BASEDIR, StringUtil.EMPTY);
+               ini.putMulti(PhpIni.SAFE_MODE, 0);
+               ini.putMulti(PhpIni.DISABLE_DEFS, PhpIni.OFF);
+               ini.putMulti(PhpIni.OUTPUT_BUFFERING, PhpIni.ON);
+               //
+               // CRITICAL
+               ini.putMulti(PhpIni.ERROR_REPORTING, 
PhpIni.E_ALL_NOTICE_WARNING);
+               // CRITICAL
+               ini.putMulti(PhpIni.DISPLAY_ERRORS, PhpIni.ON);
+               // CRITICAL
+               ini.putMulti(PhpIni.DISPLAY_STARTUP_ERRORS, PhpIni.OFF);
+               // CRITICAL
+               ini.putMulti(PhpIni.LOG_ERRORS, PhpIni.ON);
+               // CRITICAL
+               ini.putMulti(PhpIni.HTML_ERRORS, PhpIni.OFF);
+               // CRITICAL
+               ini.putMulti(PhpIni.TRACK_ERRORS, PhpIni.ON);
+               //
+               ini.putMulti(PhpIni.REPORT_MEMLEAKS, PhpIni.ON);
+               ini.putMulti(PhpIni.REPORT_ZEND_DEBUG, PhpIni.OFF);
+               ini.putMulti(PhpIni.DOCREF_ROOT, StringUtil.EMPTY);
+               ini.putMulti(PhpIni.DOCREF_EXT, PhpIni.DOT_HTML);
+               ini.putMulti(PhpIni.ERROR_PREPEND_STRING, StringUtil.EMPTY);
+               ini.putMulti(PhpIni.ERROR_APPEND_STRING, StringUtil.EMPTY);
+               ini.putMulti(PhpIni.AUTO_PREPEND_FILE, StringUtil.EMPTY);
+               ini.putMulti(PhpIni.AUTO_APPEND_FILE, StringUtil.EMPTY);
+               ini.putMulti(PhpIni.MAGIC_QUOTES_RUNTIME, PhpIni.OFF);
+               ini.putMulti(PhpIni.IGNORE_REPEATED_ERRORS, PhpIni.OFF);
+               ini.putMulti(PhpIni.PRECISION, 14);
+               ini.putMulti(PhpIni.UNICODE_RUNTIME_ENCODING, 
PhpIni.ISO_8859_1);
+               ini.putMulti(PhpIni.UNICODE_SCRIPT_ENCODING, PhpIni.UTF_8);
+               ini.putMulti(PhpIni.UNICODE_OUTPUT_ENCODING, PhpIni.UTF_8);
+               ini.putMulti(PhpIni.UNICODE_FROM_ERROR_MODE, 
PhpIni.U_INVALID_SUBSTITUTE);
+               ini.putMulti(PhpIni.SESSION_AUTO_START, PhpIni.OFF);
+               
+               // default php.ini has these extensions on Windows
+               // NOTE: this is validated by RequiredExtensionsSmokeTest. 
similar/same info is both there and here
+               //       b/c that needs it for validation and its here because 
its in the default php.ini
+               if (host.isWindows()) {
+                       ini.setExtensionDir(build.getDefaultExtensionDir());
+                       ini.addExtensions(
+                                       PhpIni.EXT_BZ2,
+                                       PhpIni.EXT_COM_DOTNET,
+                                       PhpIni.EXT_CURL,
+                                       PhpIni.EXT_FILEINFO,
+                                       PhpIni.EXT_GD2,
+                                       PhpIni.EXT_GETTEXT,
+                                       PhpIni.EXT_GMP,
+                                       PhpIni.EXT_INTL,
+                                       PhpIni.EXT_IMAP,
+                                       PhpIni.EXT_LDAP,
+                                       PhpIni.EXT_MBSTRING,
+                                       PhpIni.EXT_EXIF,
+                                       PhpIni.EXT_MYSQL,
+                                       PhpIni.EXT_MYSQLI,
+                                       PhpIni.EXT_OPENSSL,
+                                       PhpIni.EXT_PDO_MYSQL,
+                                       PhpIni.EXT_PDO_PGSQL,
+                                       PhpIni.EXT_PDO_SQLITE,
+                                       PhpIni.EXT_PDO_ODBC,
+                                       PhpIni.EXT_PGSQL,
+                                       PhpIni.EXT_SHMOP,
+                                       PhpIni.EXT_SOAP,
+                                       PhpIni.EXT_SOCKETS,
+                                       PhpIni.EXT_SQLITE3,
+                                       PhpIni.EXT_TIDY,
+                                       PhpIni.EXT_XMLRPC,
+                                       PhpIni.EXT_XSL
+                               );
+               }
+               
+               // TIMING: do this after all calls to #putMulti, etc... b/c 
that sets is_default = false
+               ini.is_default = true;
+               return ini;
+       } // end public static PhpIni createDefaultIniCopy
        
 } // end public class RequiredExtensionsSmokeTest
diff --git a/src/com/mostc/pftt/model/smoke/RequiredFeaturesSmokeTest.java 
b/src/com/mostc/pftt/model/smoke/RequiredFeaturesSmokeTest.java
index d31e617..7621bc5 100644
--- a/src/com/mostc/pftt/model/smoke/RequiredFeaturesSmokeTest.java
+++ b/src/com/mostc/pftt/model/smoke/RequiredFeaturesSmokeTest.java
@@ -258,7 +258,7 @@ public class RequiredFeaturesSmokeTest extends SmokeTest {
 "Collecting statistics => Yes%s" +
 "Collecting memory statistics => No%s" +
 "Tracing => n/a%s" +
-"Loaded plugins => 
mysqlnd,example,debug_trace,auth_plugin_mysql_native_password,auth_plugin_mysql_clear_password%s"
 +
+"Loaded plugins => %s" +
 "API Extensions => %s" +
 "%s" +
 "mysqlnd statistics =>%s" +  
@@ -423,10 +423,6 @@ public class RequiredFeaturesSmokeTest extends SmokeTest {
 "bytes_received_real_data_normal => 0%s" +
 "bytes_received_real_data_ps => 0%s" +
 "%s" +
-"example statistics =>  %s" +
-"stat1 => 0%s" +
-"stat2 => 0%s" +
-"%s" +
 "odbc%s" +
 "%s" +
 "ODBC Support => enabled%s" +
@@ -850,7 +846,7 @@ public class RequiredFeaturesSmokeTest extends SmokeTest {
 "Collecting statistics => Yes%s" +
 "Collecting memory statistics => No%s" +
 "Tracing => n/a%s" +
-"Loaded plugins => 
mysqlnd,example,debug_trace,auth_plugin_mysql_native_password,auth_plugin_mysql_clear_password%s"
 +
+"Loaded plugins => %s" +
 "API Extensions => %s" +
 "%s" +
 "mysqlnd statistics =>%s" +  
@@ -1015,10 +1011,6 @@ public class RequiredFeaturesSmokeTest extends SmokeTest 
{
 "bytes_received_real_data_normal => 0%s" +
 "bytes_received_real_data_ps => 0%s" +
 "%s" +
-"example statistics =>  %s" +
-"stat1 => 0%s" +
-"stat2 => 0%s" +
-"%s" +
 "odbc%s" +
 "%s" +
 "ODBC Support => enabled%s" +
diff --git a/src/com/mostc/pftt/model/ui/wordpress.groovy 
b/src/com/mostc/pftt/model/ui/wordpress.groovy
index 23aa1d5..f65e6a6 100644
--- a/src/com/mostc/pftt/model/ui/wordpress.groovy
+++ b/src/com/mostc/pftt/model/ui/wordpress.groovy
@@ -1,6 +1,6 @@
 package com.mostc.pftt.model.ui;
 
-import com.mostc.pftt.scenario.WordpressScenario
+import com.mostc.pftt.scenario.app.WordpressScenario
 
 // auto import UITestCase
 // cr or case_runner -
diff --git a/src/com/mostc/pftt/results/PhptResultPack.java 
b/src/com/mostc/pftt/results/PhptResultPack.java
index 5d0da0d..f2d0a0c 100644
--- a/src/com/mostc/pftt/results/PhptResultPack.java
+++ b/src/com/mostc/pftt/results/PhptResultPack.java
@@ -50,10 +50,10 @@ public abstract class PhptResultPack {
        }
        
        public static float round1(float value) {
-               float ret = (float) Math.round( ( value  * 10000.0d)/100.0d );
-               if (ret==100.0f && value!=100.0f)
+               float ret = ( (float) Math.round( value * 10.0f ) ) / 10.0f;
+               if (ret==100.0f && value<100.0f)
                        // only show 100% if its really 100%
-                       return 99.99f;
+                       return 99.9f;
                else
                        return ret;
        }
diff --git a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java 
b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java
index f650587..43a66e0 100644
--- a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java
@@ -10,12 +10,9 @@ import com.mostc.pftt.model.phpt.ESAPIType;
 import com.mostc.pftt.model.phpt.PhpBuild;
 import com.mostc.pftt.model.phpt.PhpIni;
 import com.mostc.pftt.model.phpt.PhptTestCase;
-import com.mostc.pftt.model.phpt.PhptActiveTestPack;
 import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.IPhptTestResultReceiver;
 import com.mostc.pftt.results.PhptTestResult;
-import com.mostc.pftt.scenario.AbstractINIScenario;
-import com.mostc.pftt.scenario.Scenario;
 import com.mostc.pftt.scenario.ScenarioSet;
 
 public abstract class AbstractPhptTestCaseRunner {
@@ -34,18 +31,6 @@ public abstract class AbstractPhptTestCaseRunner {
        
        public abstract void runTest() throws IOException, Exception, Throwable;
        
-       public static PhpIni createIniForTest(ConsoleManager cm, Host host, 
PhpBuild build, PhptActiveTestPack active_test_pack, ScenarioSet scenario_set) {
-               PhpIni ini = PhpIni.createDefaultIniCopy(host, build); // TODO
-               //_ini.replaceAll(test_case.getINI(active_test_pack, host));
-               for ( Scenario scenario : scenario_set ) {
-                       if (scenario instanceof AbstractINIScenario) {
-                               ((AbstractINIScenario)scenario).setup(cm, host, 
build, ini);
-                       }
-               }
-               ini.addToIncludePath(host, active_test_pack.getDirectory());
-               return ini;
-       }
-       
        public static Map<String, String> generateENVForTestCase(ConsoleManager 
cm, Host host, PhpBuild build, ScenarioSet scenario_set, PhptTestCase 
test_case) throws Exception {
                // read ENV vars from test, from its parent (if a test 
redirected to this test), and merge from scenario
                //
@@ -101,7 +86,7 @@ public abstract class AbstractPhptTestCaseRunner {
                        
                        return true;
                } else if 
(test_case.getName().contains("dba")||test_case.getName().contains("sybase")||test_case.getName().contains("snmp")||test_case.getName().contains("interbase")||test_case.getName().contains("ldap")||test_case.getName().contains("imap")||test_case.getName().contains("ftp")||test_case.getName().contains("curl")||test_case.getName().contains("sql")||test_case.getName().contains("enchant")||test_case.getName().contains("oci")||test_case.getName().contains("pcntl")||test_case.getName().contains("soap")||test_case.getName().contains("xmlrpc")||test_case.getName().contains("pdo")||test_case.getName().contains("odbc"))
 {
-                       // TODO temp - don't run these SKIPIFs without the 
scenario loaded
+                       // TODO don't run these SKIPIFs without the scenario 
loaded
                        twriter.addResult(host, scenario_set, new 
PhptTestResult(host, EPhptTestStatus.SKIP, test_case, "test would've been 
skipped", null, null, null, null, null, null, null, null, null, null, null));
                        
                        return true;
diff --git a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java 
b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java
index 0353429..d5aa2ce 100644
--- a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java
+++ b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java
@@ -133,11 +133,12 @@ public abstract class AbstractPhptTestCaseRunner2 extends 
AbstractPhptTestCaseRu
                        host.saveTextFile(test_clean, 
test_case.get(EPhptSection.CLEAN));
                } // else test_clean = null;
                
-               
+               /*
                if (StringUtil.isEmpty(ini.getExtensionDir()))
                        // this is done in PhpIni#createDefaultIniCopy if the 
host is Windows
                        // but for Linux/non-Windows, this won't have been done
                        ini.setExtensionDir(build.getDefaultExtensionDir());
+               */
                
                return true;
        } // end boolean prepare
@@ -409,7 +410,7 @@ public abstract class AbstractPhptTestCaseRunner2 extends 
AbstractPhptTestCaseRu
                        }
                        if (expected_re_match||a(test_case)) {
 
-                               twriter.addResult(host, scenario_set, new 
PhptTestResult(host, 
test_case.isXFail()?EPhptTestStatus.XFAIL_WORKS:EPhptTestStatus.PASS, 
test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, 
getShellScript(), null, null, null));
+                               twriter.addResult(host, scenario_set, new 
PhptTestResult(host, 
test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, 
output, null, null, charset, ini, env, splitCmdString(), stdin_post, 
getShellScript(), null, null, null));
                                                
                                return;
                        } 
@@ -431,7 +432,7 @@ public abstract class AbstractPhptTestCaseRunner2 extends 
AbstractPhptTestCaseRu
                                }
                                if (expected_re_match) {
 
-                                       twriter.addResult(host, scenario_set, 
new PhptTestResult(host, 
test_case.isXFail()?EPhptTestStatus.XFAIL_WORKS:EPhptTestStatus.PASS, 
test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, 
getShellScript(), null, null, null));
+                                       twriter.addResult(host, scenario_set, 
new PhptTestResult(host, 
test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, 
output, null, null, charset, ini, env, splitCmdString(), stdin_post, 
getShellScript(), null, null, null));
                                                        
                                        return;
                                }
@@ -443,7 +444,7 @@ public abstract class AbstractPhptTestCaseRunner2 extends 
AbstractPhptTestCaseRu
                        
                        if (equalsNoWS(output, 
expected)||a(test_case)||output.contains("<html>")) {
                                
-                               twriter.addResult(host, scenario_set, new 
PhptTestResult(host, 
test_case.isXFail()?EPhptTestStatus.XFAIL_WORKS:EPhptTestStatus.PASS, 
test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, 
getShellScript(), null, null, null));
+                               twriter.addResult(host, scenario_set, new 
PhptTestResult(host, 
test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, 
output, null, null, charset, ini, env, splitCmdString(), stdin_post, 
getShellScript(), null, null, null));
                                                
                                return;
                        }
@@ -460,7 +461,7 @@ public abstract class AbstractPhptTestCaseRunner2 extends 
AbstractPhptTestCaseRu
                                // compare again
                                if (equalsNoWS(output, expected)) {
                                        
-                                       twriter.addResult(host, scenario_set, 
new PhptTestResult(host, 
test_case.isXFail()?EPhptTestStatus.XFAIL_WORKS:EPhptTestStatus.PASS, 
test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, 
getShellScript(), null, null, null));
+                                       twriter.addResult(host, scenario_set, 
new PhptTestResult(host, 
test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, 
output, null, null, charset, ini, env, splitCmdString(), stdin_post, 
getShellScript(), null, null, null));
                                        
                                        return;
                                } // end if
@@ -470,7 +471,7 @@ public abstract class AbstractPhptTestCaseRunner2 extends 
AbstractPhptTestCaseRu
                        String output_trim = output.trim();
                        
                        if 
(StringUtil.isEmpty(output_trim)||a(test_case)||output.contains("<html>")) {
-                               twriter.addResult(host, scenario_set, new 
PhptTestResult(host, 
test_case.isXFail()?EPhptTestStatus.XFAIL_WORKS:EPhptTestStatus.PASS, 
test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, 
getShellScript(), null, null, null));
+                               twriter.addResult(host, scenario_set, new 
PhptTestResult(host, 
test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, 
output, null, null, charset, ini, env, splitCmdString(), stdin_post, 
getShellScript(), null, null, null));
                                
                                return;
                        }
@@ -478,56 +479,48 @@ public abstract class AbstractPhptTestCaseRunner2 extends 
AbstractPhptTestCaseRu
                
                // if here, test failed!
 
-               if (StringUtil.isNotEmpty(getCrashedSAPIOutput())) {
-                       // TODO 
-                       twriter.addResult(host, scenario_set, new 
PhptTestResult(host, EPhptTestStatus.CRASH, test_case, getCrashedSAPIOutput(), 
null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), 
null, null, preoverride_actual));
-                       
+               // generate a diff
+               String[] actual_lines = StringUtil.splitLines(output);
+               String[] expected_lines = 
StringUtil.splitLines(test_case.getExpected());
+               Diff<String> diff = new Diff<String>(expected_lines, 
actual_lines);
+
+               String expectf;
+               // generate the EXPECTF section to show the user the regular 
expression that was actually used (generated from EXPECTF section) to evaluate 
test output
+               if (test_case.containsSection(EPhptSection.EXPECTF)) {
+                       expectf = 
PhptTestCase.prepareExpectF(test_case.getTrim(EPhptSection.EXPECTF));
                } else {
-                       // test is FAIL or XFAIL_WORKS
-                       
-                       // generate a diff
-                       String[] actual_lines = StringUtil.splitLines(output);
-                       String[] expected_lines = 
StringUtil.splitLines(test_case.getExpected());
-                       Diff<String> diff = new Diff<String>(expected_lines, 
actual_lines);
-       
-                       String expectf;
-                       // generate the EXPECTF section to show the user the 
regular expression that was actually used (generated from EXPECTF section) to 
evaluate test output
-                       if (test_case.containsSection(EPhptSection.EXPECTF)) {
-                               expectf = 
PhptTestCase.prepareExpectF(test_case.getTrim(EPhptSection.EXPECTF));
-                       } else {
-                               expectf = null;
-                       }
+                       expectf = null;
+               }
 
-                       PhptTestResult result;
-                       if (test_case.isXFail()) {
-                               result = new PhptTestResult(host, 
EPhptTestStatus.XFAIL, test_case, output, null, null, charset, ini, env, 
splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual);
-                       } else {
-                               result = notifyFail(new PhptTestResult(host, 
EPhptTestStatus.FAIL, test_case, output, actual_lines, expected_lines, charset, 
ini, env, splitCmdString(), stdin_post, getShellScript(), diff, expectf, 
preoverride_actual, getCrashedSAPIOutput()));
-                       }
-                       
+               PhptTestResult result;
+               if (test_case.isXFail()) {
+                       result = new PhptTestResult(host, 
EPhptTestStatus.XFAIL_WORKS, test_case, output, null, null, charset, ini, env, 
splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual);
+               } else {
+                       result = notifyFail(new PhptTestResult(host, 
EPhptTestStatus.FAIL, test_case, output, actual_lines, expected_lines, charset, 
ini, env, splitCmdString(), stdin_post, getShellScript(), diff, expectf, 
preoverride_actual, getCrashedSAPIOutput()));
+               }
+               
+               //
+               // set result#regex_compiler_dump and result#regex_output dump 
if test result is FAIL or XFAIL_WORKS and test has an EXPECTF or EXPECTREGEX 
section
+               if (test_case.containsSection(EPhptSection.EXPECTF) || 
test_case.containsSection(EPhptSection.EXPECTREGEX)) {
+                       // test may be failing due to a bad regular expression 
in test or bug in regular expression engine
                        //
-                       // set result#regex_compiler_dump and 
result#regex_output dump if test result is FAIL or XFAIL_WORKS and test has an 
EXPECTF or EXPECTREGEX section
-                       if (test_case.containsSection(EPhptSection.EXPECTF) || 
test_case.containsSection(EPhptSection.EXPECTREGEX)) {
-                               // test may be failing due to a bad regular 
expression in test or bug in regular expression engine
-                               //
-                               // get a debug dump from the regular expression 
engine to save with the result
-                               //
-                               // (this is an expensive operation so it 
shouldn't be done for every test. there shouldn't be
-                               //  very many FAIL tests so this shouldn't be 
done very much)
-                               LengthLimitStringWriter dump_sw = new 
LengthLimitStringWriter();
-                               LengthLimitStringWriter output_sw = new 
LengthLimitStringWriter();
-                               PrintWriter dump_pw = new PrintWriter(dump_sw);
-                               PrintWriter output_pw = new 
PrintWriter(output_sw);
-                               
-                               test_case.debugExpectedRegularExpression(host, 
scenario_set, twriter, result.actual, dump_pw, output_pw);
-                               
-                               result.regex_compiler_dump = dump_sw.toString();
-                               result.regex_output = output_sw.toString();
-                       }
+                       // get a debug dump from the regular expression engine 
to save with the result
                        //
+                       // (this is an expensive operation so it shouldn't be 
done for every test. there shouldn't be
+                       //  very many FAIL tests so this shouldn't be done very 
much)
+                       LengthLimitStringWriter dump_sw = new 
LengthLimitStringWriter();
+                       LengthLimitStringWriter output_sw = new 
LengthLimitStringWriter();
+                       PrintWriter dump_pw = new PrintWriter(dump_sw);
+                       PrintWriter output_pw = new PrintWriter(output_sw);
                        
-                       twriter.addResult(host, scenario_set, result);
+                       test_case.debugExpectedRegularExpression(host, 
scenario_set, twriter, result.actual, dump_pw, output_pw);
+                       
+                       result.regex_compiler_dump = dump_sw.toString();
+                       result.regex_output = output_sw.toString();
                }
+               //
+               
+               twriter.addResult(host, scenario_set, result);
        } // end void evalTest
        
        protected PhptTestResult notifyFail(PhptTestResult result) {
diff --git a/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java 
b/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
index 794b4ad..0abd429 100644
--- a/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
@@ -19,6 +19,7 @@ import com.mostc.pftt.model.phpt.PhpIni;
 import com.mostc.pftt.model.phpt.PhptTestCase;
 import com.mostc.pftt.model.phpt.PhptSourceTestPack;
 import com.mostc.pftt.model.phpt.PhptActiveTestPack;
+import com.mostc.pftt.model.smoke.RequiredExtensionsSmokeTest;
 import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.IPhptTestResultReceiver;
 import com.mostc.pftt.results.PhptTestResult;
@@ -111,7 +112,18 @@ public class CliPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                                "ext/session/tests/023.phpt",
                                "ext/phar/tests/phar_get_supportedcomp3.phpt",
                                "ext/phar/tests/phar_create_in_cwd.phpt",
-                               
"ext/phar/tests/phar_get_supported_signatures_002.phpt"
+                               
"ext/phar/tests/phar_get_supported_signatures_002.phpt",
+                               //
+                               
"ext/standard/tests/streams/stream_get_meta_data_socket_variation2.phpt",
+                               
"ext/standard/tests/streams/stream_get_meta_data_socket_variation1.phpt",
+                               
"ext/standard/tests/network/gethostbyname_error002.phpt",
+                               "ext/session/tests/003.phpt",
+                               
"ext/standard/tests/streams/stream_get_meta_data_socket_variation3.phpt",
+                               "ext/phar/tests/phar_commitwrite.phpt",
+                               
"ext/standard/tests/file/fgets_socket_variation1.phpt",
+                               "ext/standard/tests/network/shutdown.phpt",
+                               
"ext/standard/tests/file/fgets_socket_variation2.phpt",
+                               "ext/standard/tests/network/tcp4loop.phpt"
                        )) {
                                twriter.addResult(host, scenario_set, new 
PhptTestResult(host, EPhptTestStatus.XSKIP, test_case, "test sometimes randomly 
fails, ignore it", null, null, null, null, null, null, null, null, null, null, 
null));
                                
@@ -151,6 +163,7 @@ public class CliPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
        }
        
        static boolean saved_ini = false;
+       static String ini_dir;
        
        @Override
        protected void prepareTest() throws Exception {
@@ -158,11 +171,15 @@ public class CliPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                
                //
                if (!saved_ini) {
+                       // @see CliScenario#createIniForTest
                        saved_ini = true;
                        
-                       String ini_file = build.getDefaultPhpIniPath(host, 
ESAPIType.CLI);
+                       ini_dir = host.mktempname(getClass());
+                       host.mkdirs(ini_dir);
+                       
+                       String ini_file = ini_dir + "/php.ini";
                        
-                       PhpIni def_ini = PhpIni.createDefaultIniCopy(host, 
build);
+                       PhpIni def_ini = 
RequiredExtensionsSmokeTest.createDefaultIniCopy(host, build);
                        
                        FileWriter fw = new FileWriter(ini_file);
                        fw.write(def_ini.toString());
@@ -176,8 +193,9 @@ public class CliPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                {
                        StringBuilder sb = new StringBuilder(64);
                        sb.append(selected_php_exe);
-                       // -n => critical: ignores any .ini file with the php 
build
-                       // TODO sb.append(" -n ");
+                       // -c => provide default PhpIni file
+                       sb.append(" -c ");
+                       sb.append(ini_dir);
                        sb.append(ini_settings);
                        sb.append(" -f 
\"");sb.append(host.fixPath(test_file));sb.append("\" ");
                        if (test_case.containsSection(EPhptSection.ARGS)) {
@@ -297,6 +315,12 @@ public class CliPhptTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                //      if test is taking longer than 40 seconds to run, spin 
up an additional thread to compensate (so other non-slow tests can be executed)
                output = host.exec(shell_file, Host.ONE_MINUTE, env, 
stdin_post, test_case.isNon8BitCharset()?test_case.getCommonCharset():null, 
active_test_pack.getDirectory(), thread, 40);
                
+               if (output.isCrashed() && 
StringUtil.isWhitespaceOrEmpty(output.output)) {
+                       not_crashed = false; // @see #runTest
+                       
+                       twriter.addResult(host, scenario_set, new 
PhptTestResult(host, EPhptTestStatus.CRASH, test_case, "PFTT: 
exit_code="+output.exit_code+"\n"+output.output, null, null, null, ini, env, 
null, stdin_post, null, null, null, null, output.output));
+               }
+               
                return output.output;
        } // end String executeTest
        
diff --git a/src/com/mostc/pftt/runner/HttpTestCaseRunner.java 
b/src/com/mostc/pftt/runner/HttpTestCaseRunner.java
index 5a77980..d451504 100644
--- a/src/com/mostc/pftt/runner/HttpTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/HttpTestCaseRunner.java
@@ -47,11 +47,13 @@ import com.mostc.pftt.util.StringUtil;
  */
 
 // TODO error msg should tell how many times web server was restarted
+// TODO restart a 2nd time before giving up
 public class HttpTestCaseRunner extends AbstractPhptTestCaseRunner2 {
        protected final WebServerManager smgr;
        protected final ByteArrayOutputStream request_bytes, response_bytes;
        protected WebServerInstance web = null;
        protected String cookie_str;
+       protected DebuggingHttpClientConnection conn;
        protected final HttpParams params;
        protected final HttpProcessor httpproc;
        protected final HttpRequestExecutor httpexecutor;
@@ -63,12 +65,12 @@ public class HttpTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                this.httpexecutor = httpexecutor;
                this.smgr = smgr;
                this.web = web;
-               // CRITICAL: need this to get ENV from this TestCaseGroup
+               // IMPORTANT: need this to get ENV from this TestCaseGroup
                if (env!=null && 
((env.containsKey("TEMP")&&env.get("TEMP").equals(".")) || 
(env.containsKey("TMP")&&env.get("TMP").equals(".")))) {
                        // checks for case like: 
ext/phar/commit/tar/phar_commitwrite.phpt
                        this.env = new HashMap<String,String>(7);
                        this.env.putAll(env);
-                       // TODO
+                       
                        this.env.put("TEMP", 
active_test_pack.getDirectory()+"/"+Host.dirname(test_case.getName()));
                        this.env.put("TMP", 
active_test_pack.getDirectory()+"/"+Host.dirname(test_case.getName()));
                } else {
@@ -166,8 +168,9 @@ public class HttpTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                                
"ext/standard/tests/general_functions/var_dump.phpt",
                                "ext/session/tests/003.phpt",
                                "ext/session/tests/023.phpt",
-                               
"ext/standard/tests/streams/stream_get_meta_data_socket_variation3.phpt",
-                               
"ext/standard/tests/streams/stream_get_meta_data_socket_variation4.phpt",
+                               "tests/basic/032.phpt",
+                               "tests/basic/031.phpt",
+                               "tests/basic/030.phpt",
                                /////////////////
                                // getopt returns false under web server (ok)
                                
"ext/standard/tests/general_functions/bug43293_1.phpt",
@@ -206,6 +209,12 @@ public class HttpTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                cookie_str = test_case.get(EPhptSection.COOKIE);
        }
        
+       protected void markTestAsCrash() {
+               not_crashed = false; // @see #runTest
+               
+               twriter.addResult(host, scenario_set, new PhptTestResult(host, 
EPhptTestStatus.CRASH, test_case, null, null, null, null, ini, env, null, 
stdin_post, null, null, null, null, web==null?null:web.getSAPIOutput()));
+       }
+       
        /** executes SKIPIF, TEST or CLEAN over http.
         * 
         * retries request if it times out and restarts web server if it crashes
@@ -266,7 +275,6 @@ public class HttpTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                        return sb.toString();
                }
        } // end protected String http_execute
-       
 
        protected String do_http_execute(String path, EPhptSection section, 
boolean is_replacement) throws Exception {
                path = Host.toUnixPath(path);
@@ -334,13 +342,6 @@ public class HttpTestCaseRunner extends 
AbstractPhptTestCaseRunner2 {
                }
        }
        
-       protected void markTestAsCrash() {
-               not_crashed = false; // @see #runTest
-               
-               twriter.addResult(host, scenario_set, new PhptTestResult(host, 
EPhptTestStatus.CRASH, test_case, null, null, null, null, ini, env, null, 
stdin_post, null, null, null, null, web==null?null:web.getSAPIOutput()));
-       }
-               
-       protected DebuggingHttpClientConnection conn;
        protected String do_http_get(String path) throws Exception {
                return do_http_get(path, 0);
        }
diff --git a/src/com/mostc/pftt/scenario/AbstractParallelScenario.java 
b/src/com/mostc/pftt/scenario/AbstractParallelScenario.java
index 7e72338..3375664 100644
--- a/src/com/mostc/pftt/scenario/AbstractParallelScenario.java
+++ b/src/com/mostc/pftt/scenario/AbstractParallelScenario.java
@@ -8,4 +8,9 @@ package com.mostc.pftt.scenario;
 
 public abstract class AbstractParallelScenario extends Scenario {
        
+       @Override
+       public boolean ignoreForShortName() {
+               return true;
+       }
+       
 }
diff --git a/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java 
b/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java
index 2fbf93b..f6050d5 100644
--- a/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java
+++ b/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java
@@ -84,5 +84,7 @@ public abstract class AbstractSAPIScenario extends 
AbstractSerialScenario {
         * @throws Exception
         */
        public abstract TestCaseGroupKey createTestGroupKey(ConsoleManager cm, 
Host host, PhpBuild build, ScenarioSet scenario_set, PhptActiveTestPack 
active_test_pack, PhptTestCase test_case, TestCaseGroupKey group_key) throws 
Exception;
+       
+       public abstract PhpIni createIniForTest(ConsoleManager cm, Host host, 
PhpBuild build, PhptActiveTestPack active_test_pack, ScenarioSet scenario_set);
 
 } // end public abstract class AbstractSAPIScenario
diff --git a/src/com/mostc/pftt/scenario/AbstractSMBScenario.java 
b/src/com/mostc/pftt/scenario/AbstractSMBScenario.java
index e84f723..fee0b1b 100644
--- a/src/com/mostc/pftt/scenario/AbstractSMBScenario.java
+++ b/src/com/mostc/pftt/scenario/AbstractSMBScenario.java
@@ -18,23 +18,25 @@ import com.mostc.pftt.util.StringUtil;
 public abstract class AbstractSMBScenario extends 
AbstractRemoteFileSystemScenario {
        protected final RemoteHost remote_host;
        protected final String base_file_path, base_share_name;
-       protected String share_name, file_path, unc_path, smb_path, local_drive;
+       // file path is path on server where share is stored
+       // network path is in both UNC and URL format (UNC for Windows, URL for 
Linux)
+       protected String share_name, remote_path, unc_path, url_path, 
local_path;
        
        public AbstractSMBScenario(RemoteHost remote_host, String 
base_file_path, String base_share_name) {
                this.remote_host = remote_host;
                //
                if (StringUtil.isEmpty(base_file_path))
-                       // @see SMBDeduplicationScenario
-                       base_file_path = "C:\\PFTT_Share";
+                       // fallback to a default path, @see 
SMBDeduplicationScenario
+                       base_file_path = remote_host.isWindows() ? 
"C:\\PFTT_Share" : "/var/data/PFTT_Share";
                else if (StringUtil.isEmpty(Host.basename(base_file_path)))
                        // base_file_path ~= C:\
-                       base_file_path += "PFTT_Share";
+                       base_file_path += "\\PFTT_Share";
                if (StringUtil.isNotEmpty(base_share_name))
                        base_share_name = base_share_name.trim();
                if (StringUtil.isEmpty(base_share_name)) {
                        base_share_name = Host.basename(base_file_path);
                        if (StringUtil.isEmpty(base_share_name))
-                               base_share_name = "PFTT_Share";
+                               base_share_name = "\\PFTT_Share";
                }
                //
                this.base_file_path = base_file_path;
@@ -66,13 +68,35 @@ public abstract class AbstractSMBScenario extends 
AbstractRemoteFileSystemScenar
                return createShare(cm);
        }
        
+       public boolean shareExists(ConsoleManager cm, String share_name) {
+               if (!remote_host.isWindows())
+                       return false; // XXX samba support
+               
+               try {
+                       String output_str = remote_host.execElevated("NET 
SHARE", Host.ONE_MINUTE).printOutputIfCrash(getClass(), cm).output;
+                       
+                       return output_str.contains(share_name);
+               } catch ( Exception ex ) {
+                       cm.addGlobalException(EPrintType.CANT_CONTINUE, 
"shareExists", ex, "can't tell if share exists");
+               }
+               return false;
+       }
+       
        public boolean createShare(ConsoleManager cm) {
-               for ( int i=1 ; ; ) {
-                       file_path = base_file_path + i;
+               // make a unique name for the share
+               for ( int i=1 ; i < 65535 ; i++ ) {
+                       remote_path = base_file_path + i;
                        share_name = base_share_name + i;
-                       if (!remote_host.exists(file_path))
-                               break;
+                       if (!remote_host.exists(remote_path)) {
+                               // share may still exist, but at a different 
remote file path (double check to avoid `net share` failure)
+                               if (!shareExists(cm, share_name)) {
+                                       break;
+                               }
+                       }
                }
+               //
+               
+               cm.println(EPrintType.IN_PROGRESS, getName(), "Selected 
share_name="+share_name+" remote_path="+remote_path+" (base: "+base_file_path+" 
"+base_share_name+")");
                
                try {
                        if (remote_host.isWindows()) {
@@ -82,22 +106,22 @@ public abstract class AbstractSMBScenario extends 
AbstractRemoteFileSystemScenar
                                return false;
                        }
                } catch (Exception ex ) {
-                       
cm.addGlobalException(EPrintType.OPERATION_FAILED_CONTINUING, getClass(), 
"createShare", ex, "", remote_host, file_path, share_name);
+                       
cm.addGlobalException(EPrintType.OPERATION_FAILED_CONTINUING, getClass(), 
"createShare", ex, "", remote_host, remote_path, share_name);
                        return false;
                }
                
                unc_path = "\\\\"+remote_host.getHostname()+"\\"+share_name; // 
for Windows
-               smb_path = "smb://"+remote_host.getHostname()+"/"+share_name; 
// for linux
+               url_path = "smb://"+remote_host.getHostname()+"/"+share_name; 
// for linux
                
-               cm.println(EPrintType.COMPLETED_OPERATION, getName(), "Share 
created: "+unc_path+" "+smb_path);
+               cm.println(EPrintType.COMPLETED_OPERATION, getName(), "Share 
created: unc="+unc_path+" remote_file="+remote_path+" url="+url_path);
                
                return true;
        } // end public boolean createShare
        
        protected boolean createShareWindows(ConsoleManager cm) throws 
Exception {
-               remote_host.mkdirs(file_path);
+               remote_host.mkdirs(remote_path);
                
-               return remote_host.exec("NET SHARE "+share_name+"="+file_path+" 
/Grant:"+remote_host.getUsername()+",Full", 
Host.FOUR_HOURS).printOutputIfCrash(getClass(), cm).isSuccess();
+               return remote_host.execElevated("NET SHARE 
"+share_name+"="+remote_path+" /Grant:"+remote_host.getUsername()+",Full", 
Host.FOUR_HOURS).printOutputIfCrash(getClass(), cm).isSuccess();
        }
        
        protected boolean createShareSamba() {
@@ -118,7 +142,7 @@ public abstract class AbstractSMBScenario extends 
AbstractRemoteFileSystemScenar
                        }
                } else {
                        // host is local, try using a local drive, normal file 
system operations, not SMB, etc...
-                       local_drive = file_path;
+                       local_path = remote_path;
                        
                        return true;
                }
@@ -126,17 +150,17 @@ public abstract class AbstractSMBScenario extends 
AbstractRemoteFileSystemScenar
        
        protected static final String[] DRIVES = new String[]{"H", "I", "J", 
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y"}; // 
18
        protected boolean connectFromWindows(ConsoleManager cm, Host 
local_host) throws Exception {
-               local_drive = null;
+               local_path = null;
                for ( int i=0 ; i < DRIVES.length ; i++ ) {
-                       if (remote_host.exists(DRIVES[i] + ":\\")) {
-                               local_drive = DRIVES[i] + ":";
+                       if (!local_host.exists(DRIVES[i] + ":\\")) {
+                               local_path = DRIVES[i] + ":";
                                break;
                        }
                }
-               if (local_drive==null)
+               if (local_path==null)
                        return false;
                
-               return local_host.exec("NET USE "+unc_path+" "+local_drive+" 
/user:"+remote_host.getUsername()+" /password:"+remote_host.getPassword(), 
Host.FOUR_HOURS).printOutputIfCrash(getClass(), cm).isSuccess();
+               return local_host.execElevated("NET USE "+unc_path+" 
"+local_path+" /user:"+remote_host.getUsername()+" 
/password:"+remote_host.getPassword(), 
Host.ONE_MINUTE).printOutputIfCrash(getClass(), cm).isSuccess();
        }
        
        protected boolean connectFromSamba() {
@@ -146,27 +170,35 @@ public abstract class AbstractSMBScenario extends 
AbstractRemoteFileSystemScenar
        
        @Override
        public String getTestPackStorageDir(Host host) {
-               return local_drive; // H: I: J: ... Y:
+               return local_path; // H: I: J: ... Y:
        }
        
        public boolean deleteShare(ConsoleManager cm, Host host) {
                try {
-                       if (host.execElevated("NET SHARE "+file_path+" 
/DELETE", Host.ONE_MINUTE).printOutputIfCrash(getClass(), cm).isSuccess()) {
-                               host.delete(file_path);
+                       if (host.execElevated("NET SHARE "+remote_path+" 
/DELETE", Host.ONE_MINUTE).printOutputIfCrash(getClass(), cm).isSuccess()) {
+                               try {
+                                       host.delete(remote_path);
+                                       
+                                       cm.println(EPrintType.IN_PROGRESS, 
getClass(), "Share deleted: remote_file="+remote_path+" unc="+unc_path+" 
url="+url_path);
+                               } catch ( Exception ex ) {
+                                       throw ex;
+                               }
                        
                                return true;
                        }
                } catch ( Exception ex ) {
-                       
cm.addGlobalException(EPrintType.OPERATION_FAILED_CONTINUING, getClass(), 
"deleteShare", ex, "", host, file_path);
+                       
cm.addGlobalException(EPrintType.OPERATION_FAILED_CONTINUING, getClass(), 
"deleteShare", ex, "", host, remote_path);
                }
                return false;
        }
        
        public boolean disconnect(ConsoleManager cm, Host host) {
                try {
-                       return host.exec("NET USE "+local_drive+" /DELETE", 
Host.ONE_MINUTE).printOutputIfCrash(getClass(), cm).isSuccess();
+                       if (host.exec("NET USE "+local_path+" /DELETE", 
Host.ONE_MINUTE).printOutputIfCrash(getClass(), cm).isSuccess()) {
+                               cm.println(EPrintType.IN_PROGRESS, getClass(), 
"Disconnected share: local="+local_path);
+                       }
                } catch ( Exception ex ) {
-                       
cm.addGlobalException(EPrintType.OPERATION_FAILED_CONTINUING, getClass(), 
"disconnect", ex, "", host, local_drive);
+                       
cm.addGlobalException(EPrintType.OPERATION_FAILED_CONTINUING, getClass(), 
"disconnect", ex, "", host, local_path);
                }
                return false;
        }
@@ -175,7 +207,7 @@ public abstract class AbstractSMBScenario extends 
AbstractRemoteFileSystemScenar
        public void notifyFinishedTestPack(ConsoleManager cm, Host host) {
                if (deleteShare(cm, host) && disconnect(cm, host)) {
                        // reset
-                       share_name = file_path = unc_path = smb_path = 
local_drive = null;
+                       share_name = remote_path = unc_path = url_path = 
local_path = null;
                }
        }
        
diff --git a/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java 
b/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java
index 05e5602..dd53c91 100644
--- a/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java
+++ b/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java
@@ -28,6 +28,7 @@ import 
com.mostc.pftt.model.sapi.SharedSAPIInstanceTestCaseGroupKey;
 import com.mostc.pftt.model.sapi.TestCaseGroupKey;
 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.IPhptTestResultReceiver;
 import com.mostc.pftt.runner.AbstractPhptTestCaseRunner;
@@ -110,8 +111,16 @@ public abstract class AbstractWebServerScenario extends 
AbstractSAPIScenario {
                return new HttpTestCaseRunner(group_key.getPhpIni(), 
group_key.getEnv(), params, httpproc, httpexecutor, smgr, (WebServerInstance) 
((SharedSAPIInstanceTestCaseGroupKey)group_key).getSAPIInstance(), thread, 
test_case, cm, twriter, host, scenario_set, build, src_test_pack, 
active_test_pack);
        }
        
+       @Override
+       public PhpIni createIniForTest(ConsoleManager cm, Host host, PhpBuild 
build, PhptActiveTestPack active_test_pack, ScenarioSet scenario_set) {
+               // entire PhpIni will be given to web server when its started
+               return RequiredExtensionsSmokeTest.createDefaultIniCopy(host, 
build);
+       }
+       
+       @Override
        public TestCaseGroupKey createTestGroupKey(ConsoleManager cm, Host 
host, PhpBuild build, ScenarioSet scenario_set, PhptActiveTestPack 
active_test_pack, PhptTestCase test_case, TestCaseGroupKey group_key) throws 
Exception {
                Map<String,String> env = null;
+               // ENV vars will be passed to web server manager to wrap the 
web server in when its executed
                if (test_case.containsSection(EPhptSection.ENV)) {
                        env = 
AbstractPhptTestCaseRunner.generateENVForTestCase(cm, host, build, 
scenario_set, test_case);
                        
@@ -119,7 +128,7 @@ public abstract class AbstractWebServerScenario extends 
AbstractSAPIScenario {
                }
                
                if (test_case.containsSection(EPhptSection.INI)) {
-                       PhpIni ini = 
AbstractPhptTestCaseRunner.createIniForTest(cm, host, build, active_test_pack, 
scenario_set);
+                       PhpIni ini = createIniForTest(cm, host, build, 
active_test_pack, scenario_set);
                        ini.replaceAll(test_case.getINI(active_test_pack, 
host));
                        
                        // note: don't bother comparing test case's INI with 
existing group_key's INI, PhptTestPackRunner
@@ -128,7 +137,7 @@ public abstract class AbstractWebServerScenario extends 
AbstractSAPIScenario {
                } else if (env==null && group_key!=null && 
group_key.getPhpIni().isDefault()) {
                        return group_key;
                } else {
-                       return new 
SharedSAPIInstanceTestCaseGroupKey(AbstractPhptTestCaseRunner.createIniForTest(cm,
 host, build, active_test_pack, scenario_set), env);
+                       return new 
SharedSAPIInstanceTestCaseGroupKey(createIniForTest(cm, host, build, 
active_test_pack, scenario_set), env);
                }
        } // end public TestCaseGroupKey createTestGroupKey
        
diff --git a/src/com/mostc/pftt/scenario/CLIScenario.java 
b/src/com/mostc/pftt/scenario/CLIScenario.java
index d1cd5b8..fce286d 100644
--- a/src/com/mostc/pftt/scenario/CLIScenario.java
+++ b/src/com/mostc/pftt/scenario/CLIScenario.java
@@ -50,11 +50,19 @@ public class CliScenario extends AbstractSAPIScenario {
        public ESAPIType getSAPIType() {
                return ESAPIType.CLI;
        }
+       
+       @Override
+       public PhpIni createIniForTest(ConsoleManager cm, Host host, PhpBuild 
build, PhptActiveTestPack active_test_pack, ScenarioSet scenario_set) {
+               // default PhpIni will be given to php.exe using a file... @see 
CliPhptTestCaseRunner#prepare
+               //
+               // this is needed only to collect any custom directives that a 
test case provides
+               return new PhpIni();
+       }
 
        @Override
        public TestCaseGroupKey createTestGroupKey(ConsoleManager cm, Host 
host, PhpBuild build, ScenarioSet scenario_set, PhptActiveTestPack 
active_test_pack, PhptTestCase test_case, TestCaseGroupKey group_key) {
                if (test_case.containsSection(EPhptSection.INI)) {
-                       PhpIni ini = 
AbstractPhptTestCaseRunner.createIniForTest(cm, host, build, active_test_pack, 
scenario_set);
+                       PhpIni ini = createIniForTest(cm, host, build, 
active_test_pack, scenario_set);
                        ini.replaceAll(test_case.getINI(active_test_pack, 
host));
                        
                        // note: don't bother comparing test case's INI with 
existing group_key's INI, PhptTestPackRunner
@@ -68,7 +76,7 @@ public class CliScenario extends AbstractSAPIScenario {
                } else if (group_key!=null && 
group_key.getPhpIni().isDefault()) {
                        return group_key;
                } else {
-                       return new 
TestCaseGroupKey(AbstractPhptTestCaseRunner.createIniForTest(cm, host, build, 
active_test_pack, scenario_set), null);
+                       return new TestCaseGroupKey(createIniForTest(cm, host, 
build, active_test_pack, scenario_set), null);
                }
        } // end public TestCaseGroupKey createTestGroupKey
        
diff --git a/src/com/mostc/pftt/scenario/NoCodeCacheScenario.java 
b/src/com/mostc/pftt/scenario/NoCodeCacheScenario.java
index c32d645..c319874 100644
--- a/src/com/mostc/pftt/scenario/NoCodeCacheScenario.java
+++ b/src/com/mostc/pftt/scenario/NoCodeCacheScenario.java
@@ -15,6 +15,11 @@ import com.mostc.pftt.results.ConsoleManager;
 public class NoCodeCacheScenario extends AbstractCodeCacheScenario {
 
        @Override
+       public boolean isPlaceholder() {
+               return true;
+       }
+       
+       @Override
        public String getName() {
                return "No-Code-Cache";
        }
diff --git a/src/com/mostc/pftt/scenario/NoDebugScenario.java 
b/src/com/mostc/pftt/scenario/NoDebugScenario.java
index dd5a037..1ace267 100644
--- a/src/com/mostc/pftt/scenario/NoDebugScenario.java
+++ b/src/com/mostc/pftt/scenario/NoDebugScenario.java
@@ -14,6 +14,11 @@ import com.mostc.pftt.results.ConsoleManager;
 public class NoDebugScenario extends AbstractDebugScenario {
 
        @Override
+       public boolean isPlaceholder() {
+               return true;
+       }
+       
+       @Override
        public boolean setup(ConsoleManager cm, Host host, PhpBuild build, 
PhpIni ini) {
                return false;
        }
diff --git a/src/com/mostc/pftt/scenario/PlainSocketScenario.java 
b/src/com/mostc/pftt/scenario/PlainSocketScenario.java
index 570400e..6274f63 100644
--- a/src/com/mostc/pftt/scenario/PlainSocketScenario.java
+++ b/src/com/mostc/pftt/scenario/PlainSocketScenario.java
@@ -14,6 +14,11 @@ import com.mostc.pftt.results.ConsoleManager;
 public class PlainSocketScenario extends AbstractSocketScenario {
 
        @Override
+       public boolean isPlaceholder() {
+               return true;
+       }
+       
+       @Override
        public String getName() {
                return "Plain-Socket";
        }
diff --git a/src/com/mostc/pftt/scenario/SMBBasicScenario.java 
b/src/com/mostc/pftt/scenario/SMBBasicScenario.java
index 02028d9..cdfafac 100644
--- a/src/com/mostc/pftt/scenario/SMBBasicScenario.java
+++ b/src/com/mostc/pftt/scenario/SMBBasicScenario.java
@@ -2,7 +2,7 @@ package com.mostc.pftt.scenario;
 
 import com.mostc.pftt.host.RemoteHost;
 
-/** Tests running a PHP build and its test pack both stored remotely on a 
basic SMB file share. (NOT IMPLEMENTED)
+/** Tests running a PHP build and its test pack both stored remotely on a 
basic SMB file share.
  * 
  * @author Matt Ficken
  *
diff --git a/src/com/mostc/pftt/scenario/SMBCAScenario.java 
b/src/com/mostc/pftt/scenario/SMBCAScenario.java
index 157f36c..22bf878 100644
--- a/src/com/mostc/pftt/scenario/SMBCAScenario.java
+++ b/src/com/mostc/pftt/scenario/SMBCAScenario.java
@@ -2,6 +2,7 @@ package com.mostc.pftt.scenario;
 
 import com.mostc.pftt.host.Host;
 import com.mostc.pftt.host.RemoteHost;
+import com.mostc.pftt.host.TempFileExecOutput;
 import com.mostc.pftt.results.ConsoleManager;
 
 /** Tests PHP using SMB Continuous Availability (CA) (NOT IMPLEMENTED)
@@ -24,7 +25,9 @@ public class SMBCAScenario extends AbstractSMBScenario {
        
        @Override
        protected boolean createShareWindows(ConsoleManager cm) throws 
Exception {
-               return remote_host.exec("Powershell -Command{New-SmbShare -Name 
"+share_name+" -Path "+file_path+" -Scope "+remote_host.getHostname()+" 
-FullControl "+remote_host.getHostname()+"\\"+remote_host.getUsername()+"}", 
Host.FOUR_HOURS).printOutputIfCrash(getClass(), cm).isSuccess();
+               TempFileExecOutput teo = remote_host.powershell(getClass(), cm, 
"New-SmbShare -Name "+share_name+" -Path "+remote_path+" -Scope 
"+remote_host.getHostname()+" -FullControl 
"+remote_host.getHostname()+"\\"+remote_host.getUsername(), Host.ONE_MINUTE);
+               teo.printOutputIfCrash(getClass(), cm);
+               return teo.cleanupIfSuccess(remote_host);
        }
 
        @Override
@@ -34,7 +37,7 @@ public class SMBCAScenario extends AbstractSMBScenario {
        
        @Override
        public boolean isImplemented() {
-               return true;
+               return false;
        }
 
 } // end public class SMBCAScenario
diff --git a/src/com/mostc/pftt/scenario/SMBDFSRScenario.java 
b/src/com/mostc/pftt/scenario/SMBDFSRScenario.java
index 082c871..e0b8c5c 100644
--- a/src/com/mostc/pftt/scenario/SMBDFSRScenario.java
+++ b/src/com/mostc/pftt/scenario/SMBDFSRScenario.java
@@ -2,11 +2,12 @@ package com.mostc.pftt.scenario;
 
 import com.mostc.pftt.host.Host;
 import com.mostc.pftt.host.RemoteHost;
+import com.mostc.pftt.host.TempFileExecOutput;
 import com.mostc.pftt.model.phpt.PhpBuild;
 import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.ConsoleManager.EPrintType;
 
-/** Tests PHP with PHP build and test pack being stored remotely on a group of 
DFS-R SMB Shares. (NOT IMPLEMENTED)
+/** Tests PHP with PHP build and test pack being stored remotely on a group of 
DFS-R SMB Shares.
  * 
  * Web hosters can setup a share that is physically copied and served by 
multiple SMB Servers.
  * 
@@ -17,13 +18,21 @@ import com.mostc.pftt.results.ConsoleManager.EPrintType;
  * There are two types of DFS, DFS-N and DFS-R, this tests DFS-R. DFS-N is not 
relevant because it only replicates a namespace(folder structure)
  * across servers. DFS-R synchronizes folder contents efficiently between file 
servers across LANs and even WANs.
  * 
- * @see `dfsutil`, `dfscmd` and `dfsdiag`
+ * @see `dfsutil`, `dfscmd` and `dfsdiag` and `fsutil reparsepoint query 
<file>`
+ * @see 
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365511%28v=vs.85%29.aspx
  * @author Matt Ficken
  *
  */
 
 public class SMBDFSRScenario extends AbstractSMBScenario {
 
+       // TODO PFTT-NS-1 PFTT-DFS-1 PFTT-TARGET-1
+       // TODO use only ip addresses
+       //    -still have problems with netbios name resolution
+       public SMBDFSRScenario(RemoteHost remote_host) {
+               this(remote_host, null, null);
+       }
+       
        public SMBDFSRScenario(RemoteHost remote_host, String base_file_path, 
String base_share_name) {
                super(remote_host, base_file_path, base_share_name);
        }
@@ -34,31 +43,29 @@ public class SMBDFSRScenario extends AbstractSMBScenario {
        }
        
        @Override
-       public boolean setup(ConsoleManager cm, Host host, PhpBuild build, 
ScenarioSet scenario_set) {
+       public boolean setup(ConsoleManager cm, Host local_host, PhpBuild 
build, ScenarioSet scenario_set) {
                StringBuilder ps_sb = new StringBuilder();
                ps_sb.append("Import-Module ServerManager\n");
                ps_sb.append("Add-WindowsFeature -name File-Services\n");
                ps_sb.append("Add-WindowsFeature -name FS-DFS\n");
                ps_sb.append("Add-WindowsFeature -name FS-DFS-Replication\n");
                
-               String tmp_file = host.mktempname(getName(), "ps1");
-               
                try {
-                       host.saveTextFile(tmp_file, ps_sb.toString());
-                                       
-                       if (host.exec("Powershell -File "+tmp_file, 
Host.FOUR_HOURS).printOutputIfCrash(getClass(), cm).isSuccess()) {
-                               host.delete(tmp_file);
+                       TempFileExecOutput teo = 
remote_host.powershell(getClass(), cm, ps_sb, Host.FOUR_HOURS);
+                       
+                       if (teo.printOutputIfCrash(getClass(), cm).isSuccess()) 
{
+                               teo.cleanup(remote_host);
                                
-                               if (super.setup(cm, host, build, scenario_set)) 
{
-                                       
cm.println(EPrintType.COMPLETED_OPERATION, getName(), "DFSR setup successfully 
on "+unc_path+" "+smb_path);
+                               if (super.setup(cm, remote_host, build, 
scenario_set)) {
+                                       
cm.println(EPrintType.COMPLETED_OPERATION, getName(), "DFSR setup successfully: 
unc="+unc_path+" remote_file="+remote_path);
                                        
                                        return true;
                                }
                        } else {
-                               
cm.println(EPrintType.OPERATION_FAILED_CONTINUING, getName(), "can't exec 
powershell script: "+tmp_file);
+                               
cm.println(EPrintType.OPERATION_FAILED_CONTINUING, getName(), "can't exec 
powershell script: "+ps_sb);
                        }
                } catch ( Exception ex ) {
-                       
cm.addGlobalException(EPrintType.OPERATION_FAILED_CONTINUING, getClass(), 
"setup", ex, "", host, tmp_file, unc_path);
+                       
cm.addGlobalException(EPrintType.OPERATION_FAILED_CONTINUING, getClass(), 
"setup", ex, "", remote_host, ps_sb, unc_path);
                }
                return false;
        }
diff --git a/src/com/mostc/pftt/scenario/SMBDeduplicationScenario.java 
b/src/com/mostc/pftt/scenario/SMBDeduplicationScenario.java
index ba8ee99..43b54a3 100644
--- a/src/com/mostc/pftt/scenario/SMBDeduplicationScenario.java
+++ b/src/com/mostc/pftt/scenario/SMBDeduplicationScenario.java
@@ -2,11 +2,12 @@ package com.mostc.pftt.scenario;
 
 import com.mostc.pftt.host.Host;
 import com.mostc.pftt.host.RemoteHost;
+import com.mostc.pftt.host.TempFileExecOutput;
 import com.mostc.pftt.model.phpt.PhpBuild;
 import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.ConsoleManager.EPrintType;
 
-/** Tests the new Remote Data Deduplication feature of Windows 2012 using SMB. 
(NOT IMPLEMENTED)
+/** Tests the new Remote Data Deduplication feature of Windows 2012 using SMB.
  * 
  * This feature broke PHP in php bug #63241. This scenario will catch that or 
any other problems Deduplication causes to PHP.
  * 
@@ -60,14 +61,18 @@ public class SMBDeduplicationScenario extends 
AbstractSMBScenario {
        @Override
        public boolean notifyPrepareStorageDir(ConsoleManager cm, Host 
local_host) {
                // check that its win8
-               if (!remote_host.isWin8OrLater()) {
+               System.out.println("64");
+               // TODO 
+               if (false) { // TODO !remote_host.isWin8OrLater()) {
+                       System.out.println("66");
                        cm.println(EPrintType.XSKIP_OPERATION, getName(), 
"Scenario can only be run against a Windows 8/2012+ host");
                        return false;
                } else if 
(volume.equals("C:")||remote_host.getSystemDrive().equalsIgnoreCase(volume)) {
+                       System.out.println("70");
                        cm.println(EPrintType.XSKIP_OPERATION, getName(), "Can 
not use Deduplication on a Windows System Drive (ex: C:\\)");
                        return false;
                }
-               
+               System.out.println("74");
                StringBuilder ps_sb = new StringBuilder(128);
                // install deduplication feature
                ps_sb.append("Import-Module ServerManager\n");
@@ -79,25 +84,24 @@ public class SMBDeduplicationScenario extends 
AbstractSMBScenario {
                // change min file age (default is 5 days which will prevent 
testing test-packs now)
                ps_sb.append("Set-DedupVolume 
");ps_sb.append(volume);ps_sb.append(" -MinimumFileAgeDays 0\n");
                
-               String tmp_file = remote_host.mktempname(getName(), "ps1");
-               
                // create PowerShell script to install and enable deduplication
                try {
-                       remote_host.saveTextFile(tmp_file, ps_sb.toString());
-                       
                        // 
-                       if (remote_host.execElevated("powershell -File 
"+tmp_file, Host.ONE_MINUTE * 10).printOutputIfCrash(getClass(), 
cm).isSuccess()) {
+                       System.out.println("89");
+                       cm.println(EPrintType.IN_PROGRESS, getName(), "Starting 
to enable Deduplication on: "+remote_host);
+                       TempFileExecOutput teo = 
remote_host.powershell(getClass(), cm, ps_sb, Host.ONE_MINUTE * 10);
+                       if (teo.printOutputIfCrash(getClass(), cm).isSuccess()) 
{
                                // don't delete tmp_file if it failed to help 
user see why
-                               remote_host.delete(tmp_file);
+                               teo.cleanup(remote_host);
                        }
                        
                        // create share on volume
                        if (super.notifyPrepareStorageDir(cm, local_host)) {
-                               cm.println(EPrintType.COMPLETED_OPERATION, 
getName(), "Deduplication enabled on share: "+unc_path+" "+smb_path);
+                               cm.println(EPrintType.COMPLETED_OPERATION, 
getName(), "Deduplication enabled on share: unc="+unc_path+" 
local="+local_path+" url="+url_path);
                                return true;
                        }
                } catch ( Exception ex ) {
-                       cm.addGlobalException(EPrintType.CANT_CONTINUE, 
getClass(), "notifyPrepareStorageDir", ex, "Unable to enable deduplication", 
remote_host, tmp_file);
+                       cm.addGlobalException(EPrintType.CANT_CONTINUE, 
getClass(), "notifyPrepareStorageDir", ex, "Unable to enable deduplication", 
remote_host, ps_sb);
                }
                return false;
        } // end public boolean notifyPrepareStorageDir
@@ -111,9 +115,9 @@ public class SMBDeduplicationScenario extends 
AbstractSMBScenario {
        public boolean notifyTestPackInstalled(ConsoleManager cm, Host 
local_host) {
                try {
                        // run deduplication job (on test-pack) -wait for 
completion
-                       cm.println(EPrintType.IN_PROGRESS, getName(), "Running 
deduplication job...");
-                       if (remote_host.exec("powershell -Command 
{Start-Dedupjob -Volume "+volume+" -Type Optimization -Wait}", 
Host.FOUR_HOURS).printOutputIfCrash(getClass(), cm).isSuccess()) {
-                               cm.println(EPrintType.COMPLETED_OPERATION, 
getName(), "Deduplication completed successfully.");
+                       cm.println(EPrintType.IN_PROGRESS, getName(), "Running 
deduplication job... unc="+unc_path+" local="+local_path+" 
remote_file="+remote_path+" url="+url_path);
+                       if (remote_host.powershell(getClass(), cm, 
"Start-Dedupjob -Volume "+volume+" -Type Optimization", 
Host.FOUR_HOURS).printOutputIfCrash(getClass(), cm).isSuccess()) {
+                               cm.println(EPrintType.COMPLETED_OPERATION, 
getName(), "Deduplication completed successfully. unc="+unc_path+" 
local="+local_path+" remote_file="+remote_path+" url="+url_path);
                                return true;
                        } else {
                                
cm.println(EPrintType.OPERATION_FAILED_CONTINUING, getName(), "Deduplication 
failed");
@@ -122,12 +126,12 @@ public class SMBDeduplicationScenario extends 
AbstractSMBScenario {
                        cm.addGlobalException(EPrintType.CANT_CONTINUE, 
getClass(), "notifyTestPackInstalled", ex, "Deduplication failed", remote_host, 
local_host, volume);
                }
                return false;
-       }
+       } // end public boolean notifyTestPackInstalled
        
        @Override
        public String getName() {
                return "SMB-Deduplication";
-       }
+       } 
        
        @Override
        public boolean isImplemented() {
diff --git a/src/com/mostc/pftt/scenario/Scenario.java 
b/src/com/mostc/pftt/scenario/Scenario.java
index 562815e..2d6b558 100644
--- a/src/com/mostc/pftt/scenario/Scenario.java
+++ b/src/com/mostc/pftt/scenario/Scenario.java
@@ -57,6 +57,14 @@ public abstract class Scenario {
        public void getENV(Map<String, String> env) {
                
        }
+       
+       public boolean isPlaceholder() {
+               return false;
+       }
+       
+       public boolean ignoreForShortName() {
+               return false;
+       }
 
        public boolean hasENV() {
                return false;
diff --git a/src/com/mostc/pftt/scenario/ScenarioSet.java 
b/src/com/mostc/pftt/scenario/ScenarioSet.java
index 156e95e..4060f84 100644
--- a/src/com/mostc/pftt/scenario/ScenarioSet.java
+++ b/src/com/mostc/pftt/scenario/ScenarioSet.java
@@ -66,15 +66,14 @@ public class ScenarioSet extends ArrayList<Scenario> {
                StringBuilder sb = new StringBuilder(40);
                String str;
                for ( Scenario s : this ) {
-                       if (sb.length()>0)
+                       if (s.isPlaceholder())
+                               continue;
+                       else if (sb.length()>0)
                                sb.append('_');
                        str = s.toString();
-                       if (str.startsWith("No-"))
-                               // ignore these scenarios, they're placeholders
-                               continue;
                        sb.append(str);
                }
-               str = sb.toString();
+               this.str = sb.toString();
        }
        
        protected void forceSort() {
@@ -91,10 +90,26 @@ public class ScenarioSet extends ArrayList<Scenario> {
        
        @Override
        public String toString() {
+               return getName();
+       }
+       
+       public String getName() {
                ensureSorted();
                return str; // @see #sort
        }
        
+       public String getShortName() {
+               StringBuilder sb = new StringBuilder();
+               for ( Scenario s : this ) {
+                       if (s.ignoreForShortName())
+                               continue;
+                       else if (sb.length()>0)
+                               sb.append('_');
+                       sb.append(s.getName());
+               }
+               return sb.toString();
+       }
+       
        @Override
        public boolean add(Scenario s) {
                super.add(s);
diff --git a/src/com/mostc/pftt/ui/PhptHostTab.java 
b/src/com/mostc/pftt/ui/PhptHostTab.java
index a31b73f..73d7db2 100644
--- a/src/com/mostc/pftt/ui/PhptHostTab.java
+++ b/src/com/mostc/pftt/ui/PhptHostTab.java
@@ -86,12 +86,12 @@ public class PhptHostTab extends JSplitPane {
                                        stop_button.setEnabled(false);
                                }
                        });
-               panel.add("left", new JLabel("Pass"));
-               panel.add("left", pass_label = new JLabel("0"));
-               panel.add("left", pass_bar = new JProgressBar(0, 12000)); // 
#showResult updates pass_bar maximum
-               pass_bar.setStringPainted(true);
                panel.add("left", new JLabel("Total"));
                panel.add("left", total_label = new JLabel("0"));
+               panel.add("left", pass_bar = new JProgressBar(0, 12000)); // 
#showResult updates pass_bar maximum
+               pass_bar.setStringPainted(true);
+               panel.add("left", new JLabel("Pass"));
+               panel.add("left", pass_label = new JLabel("0"));
                panel.add("left", new JLabel("Fail"));
                panel.add("left", fail_label = new JLabel("0"));
                panel.add(new JLabel("CRASH"));
@@ -305,9 +305,9 @@ public class PhptHostTab extends JSplitPane {
                                                fail++;
                                                
fail_label.setText(Integer.toString(fail));
                                                
-                                               
pass_bar.setString(Float.toString(PhptResultPack.round1( (float)( ((float)pass) 
/ ((float)( pass + fail + crash )) )))+"%"); // 1 decimal places nn.y
+                                               
pass_bar.setString(Float.toString(PhptResultPack.round1( (float)( ( 100.0f * 
pass) / ((float)( pass + fail +crash )) )))+"%"); // 1 decimal place nn.y
                                                pass_bar.setMaximum(fail+pass);
-                                               
total_label.setText(""+(fail+pass));
+                                               
total_label.setText(""+(fail+pass+crash));
                                                
                                                // show in list
                                                
fail_list_model.addElement(result);
@@ -350,7 +350,7 @@ public class PhptHostTab extends JSplitPane {
                                                break;
                                        case PASS:
                                                pass++;
-                                               
pass_bar.setString(Float.toString(PhptResultPack.round1( (float)( (double)pass 
/ ((double)( pass + fail )) )))+"%"); // 1 decimal places nn.y
+                                               
pass_bar.setString(Float.toString(PhptResultPack.round1( (float)( ( 100.0f * 
pass) / ((float)( pass + fail + crash )) )))+"%"); // 1 decimal place nn.y
                                                
                                                
                                                pass_bar.setValue(pass);
diff --git a/src/com/mostc/pftt/util/StringUtil.java 
b/src/com/mostc/pftt/util/StringUtil.java
index 92aa87c..6c83783 100644
--- a/src/com/mostc/pftt/util/StringUtil.java
+++ b/src/com/mostc/pftt/util/StringUtil.java
@@ -19,6 +19,15 @@ import com.mostc.pftt.util.apache.regexp.REProgram;
 public final class StringUtil {
        public static final String EMPTY = "";
        
+       public static String chomp(String in) {
+               if (in.endsWith("\r\n"))
+                       return in.substring(0, in.length()-2);
+               else if (in.endsWith("\n"))
+                       return in.substring(0, in.length()-1);
+               else
+                       return in;
+       }
+       
        public static String unquote(String in) {
                if (isEmpty(in))
                        return in;
@@ -277,7 +286,7 @@ public final class StringUtil {
                StringBuilder sb = new StringBuilder(256);
                sb.append(parts[off]);
                off++;
-               for ( int i=0 ; i < len ; i++, off++ ) {
+               for ( int i=0 ; i < len && off < parts.length ; i++, off++ ) {
                        sb.append(delim);
                        sb.append(parts[off]);
                }
@@ -402,6 +411,19 @@ public final class StringUtil {
                
        } // end public static class LengthLimitStringWriter
        
+       public static boolean isWhitespaceOrEmpty(String a) {
+               if (a==null)
+                       return true;
+               final int a_len = a.length();
+               if (a_len==0)
+                       return true;
+               for ( int i=0 ; i < a_len ; i++ ) {
+                       if (!Character.isLetter(a.charAt(i)))
+                               return false;
+               }
+               return true;
+       }
+       
        private StringUtil() {}
        
 } // end public class StringUtil
diff --git a/src/org/apache/sshd/server/filesystem/NativeSshFile.java 
b/src/org/apache/sshd/server/filesystem/NativeSshFile.java
index cac0bc0..cb893aa 100644
--- a/src/org/apache/sshd/server/filesystem/NativeSshFile.java
+++ b/src/org/apache/sshd/server/filesystem/NativeSshFile.java
@@ -71,7 +71,7 @@ public class NativeSshFile implements SshFile {
 
         if (fileName.length() == 0) {
             throw new IllegalArgumentException("fileName can not be empty");
-        } else if (fileName.charAt(0) != '/') {
+        } else if (fileName.charAt(0) != '/' && 
(fileName.length()<2||!Character.isLetter(fileName.charAt(0))||fileName.charAt(1)!=':'))
 {
             throw new IllegalArgumentException("fileName must be an absolute 
path");
         }
 
@@ -552,7 +552,11 @@ public class NativeSshFile implements SshFile {
                 .length())) {
             resArg = normalizedRootDir;
         }
-
+        System.out.println("555 "+resArg);
+        int i = resArg.lastIndexOf(':');
+        if (i>0)
+               resArg = resArg.substring(i-1);
+        System.out.println("559 "+resArg);
         return resArg;
     }

Reply via email to