Commit:    6559b74b30ff295f92dc1b94571be138204df75b
Author:    Matt Ficken <v-maf...@microsoft.com>         Wed, 12 Jun 2013 
22:33:30 -0700
Parents:   eca7d4fc66aaa4f8eaa3cb61e9551c9a7cfbe3ea
Branches:  master

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

Log:
use HTTP instead of TCP to check web server is ready


Former-commit-id: 07941a5e63378102aabecbb8da91a64023c02223

Changed paths:
  M  src/com/mostc/pftt/main/PfttMain.java
  M  src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java
  M  src/com/mostc/pftt/model/sapi/ApacheManager.java
  M  src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java
  M  src/com/mostc/pftt/model/sapi/IISManager.java
  M  src/com/mostc/pftt/model/sapi/WebServerManager.java
  M  src/com/mostc/pftt/results/PhpUnitResultReader.java
  M  src/com/mostc/pftt/results/PhptResultWriter.java

diff --git a/src/com/mostc/pftt/main/PfttMain.java 
b/src/com/mostc/pftt/main/PfttMain.java
index 3356b6b..3a94984 100644
--- a/src/com/mostc/pftt/main/PfttMain.java
+++ b/src/com/mostc/pftt/main/PfttMain.java
@@ -79,7 +79,11 @@ import 
com.mostc.pftt.util.WindowsSnapshotDownloadUtil.FindBuildTestPackPair;
 // doesn't resort to brittle shell scripts
 
 // TODO http request to web server to make sure its running (instead of just 
tcp socket)
+// TODO for SKIP and XSKIP tests, include output and sapi-output in result-pack
 // TODO mysql, postgresql scenario
+// TODO create TIMEOUT status for PHPT and phpunit tests
+//      modify evaluation critieria to mark those tests as TIMEOUT
+//      add TIMEOUT status to report pages (list at end of report ; highlight 
summary in yellow if TIMEOUT > 0)
 // TODO valgrind gdb?
 // TODO linux installer
  
diff --git 
a/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java 
b/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java
index bf4c910..b3642f4 100644
--- 
a/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java
+++ 
b/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java
@@ -1,13 +1,17 @@
 package com.mostc.pftt.model.sapi;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.Socket;
+import java.net.URL;
+import java.net.URLConnection;
 import java.util.Map;
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import com.github.mattficken.Overridable;
 import com.mostc.pftt.host.AHost;
 import com.mostc.pftt.host.LocalHost;
 import com.mostc.pftt.host.AHost.ExecHandle;
@@ -60,26 +64,62 @@ public abstract class 
AbstractManagedProcessesWebServerManager extends WebServer
                public int attempts;
        }
        
-       public static CouldConnect canConnect(String listen_address, int port) {
+       /** makes sure the web server is running and accepting connections.
+        * 
+        * @param listen_address
+        * @param port
+        * @param double_sure - if TRUE, sends HTTP request, if FALSE just does 
TCP socket.
+        *                      TCP (!double_sure) is much faster, HTTP is much 
slower (only use HTTP when you think it might not work)
+        * @return
+        */
+       public static CouldConnect canConnect(String listen_address, int port, 
boolean double_sure) {
                Socket sock = null;
                CouldConnect could = new CouldConnect();
                could.start_time = System.currentTimeMillis();
-               // builtin web server needs many attempts and large timeouts
-               for ( could.attempts=0 ; could.attempts < 10 ; could.attempts++ 
) {
-                       could.connect = false;
-                       try {
-                               sock = new Socket();
-                               sock.setSoTimeout(Math.max(200, Math.min(60000, 
100*((int)(Math.pow(could.attempts+1, could.attempts+1))))));
-                               sock.connect(new 
InetSocketAddress(listen_address, port));
-                               if (sock.isConnected()) {
+               
+               if (double_sure) {
+                       for ( could.attempts=0 ; could.attempts < 10 ; 
could.attempts++ ) {
+                               could.connect = false;
+                               
+                               try {
+                                       final int timeout = Math.max(200, 
Math.min(60000, 100*((int)(Math.pow(could.attempts+1, could.attempts+1)))));
+                                       
+                                       URL url = new 
URL("http://"+listen_address+":"+port+"/";);
+                                       URLConnection uc = url.openConnection();
+                                       uc.setConnectTimeout(timeout);
+                                       uc.setReadTimeout(timeout);
+                                       uc.connect();
+                                       uc.getInputStream();
+                                               
                                        could.connect = true;
                                        return could;
+                               } catch ( FileNotFoundException ex ) {
+                                       // got HTTP 404 response from web 
server - which means its up and responding to HTTP requests
+                                       // (regardless of whether or not that 
page actually exists)
+                                       could.connect = true;
+                                       return could;
+                               } catch ( IOException ex ) {
+                                       // did not get HTTP response (may not 
have been able to do TCP connect/accept even)
                                }
-                       } catch ( IOException ex ) {
-                       } finally {
+                       }
+               } else {
+                       // builtin web server needs many attempts and large 
timeouts
+                       for ( could.attempts=0 ; could.attempts < 10 ; 
could.attempts++ ) {
+                               could.connect = false;
                                try {
-                                       sock.close();
-                               } catch (IOException e) {
+                                       sock = new Socket();
+                                       sock.setSoTimeout(Math.max(200, 
Math.min(60000, 100*((int)(Math.pow(could.attempts+1, could.attempts+1))))));
+                                       sock.connect(new 
InetSocketAddress(listen_address, port));
+                                       if (sock.isConnected()) {
+                                               could.connect = true;
+                                               return could;
+                                       }
+                               } catch ( IOException ex ) {
+                               } finally {
+                                       try {
+                                               sock.close();
+                                       } catch (IOException e) {
+                                       }
                                }
                        }
                }
@@ -89,7 +129,7 @@ public abstract class 
AbstractManagedProcessesWebServerManager extends WebServer
        
        static final int MAX_TOTAL_ATTEMPTS = 3;
        @Override
-       protected WebServerInstance createWebServerInstance(ConsoleManager cm, 
AHost host, ScenarioSet scenario_set, PhpBuild build, PhpIni ini, 
Map<String,String> env, final String docroot, final boolean debugger_attached, 
final Object server_name) {
+       protected WebServerInstance createWebServerInstance(ConsoleManager cm, 
AHost host, ScenarioSet scenario_set, PhpBuild build, PhpIni ini, 
Map<String,String> env, final String docroot, final boolean debugger_attached, 
final Object server_name, boolean is_replacement) {
                String sapi_output = "";
                int port_attempts;
                boolean found_port;
@@ -137,7 +177,12 @@ public abstract class 
AbstractManagedProcessesWebServerManager extends WebServer
                                final AHost.ExecHandle handlef = handle;
                                                                
                                // ensure server can be connected to
-                               CouldConnect could = canConnect(listen_address, 
port); 
+                               //
+                               // only use HTTP to check, if its a replacement 
web server
+                               // this makes a real difference in test speed: 
use TCP only for the first web server
+                               //    (since most of the time it will work, web 
servers that have to be replaced are the ones
+                               //     to likely have a problem)
+                               CouldConnect could = 
_canConnect(listen_address, port, is_replacement); 
                                if (!could.connect) {
                                        // kill server and try again
                                        throw new IOException("Could not socket 
to web server after it was started. Web server did not respond to socket. Tried 
"+could.attempts+" times, waiting 
"+(System.currentTimeMillis()-could.start_time)+" millis total.");
@@ -207,6 +252,11 @@ public abstract class 
AbstractManagedProcessesWebServerManager extends WebServer
                return new CrashedWebServerInstance(this, ini, env, 
sapi_output);
        } // end protected WebServerInstance createWebServerInstance
        
+       @Overridable
+       protected CouldConnect _canConnect(String listen_address, int port, 
boolean is_replacement) {
+               return canConnect(listen_address, port, is_replacement);
+       }
+
        protected abstract ManagedProcessWebServerInstance 
createManagedProcessWebServerInstance(ConsoleManager cm, AHost host, 
ScenarioSet scenario_set, PhpBuild build, PhpIni ini, Map<String, String> env, 
String docroot, String listen_address, int port);
        
        public abstract class ManagedProcessWebServerInstance extends 
WebServerInstance {
diff --git a/src/com/mostc/pftt/model/sapi/ApacheManager.java 
b/src/com/mostc/pftt/model/sapi/ApacheManager.java
index dfb987d..0bf9910 100644
--- a/src/com/mostc/pftt/model/sapi/ApacheManager.java
+++ b/src/com/mostc/pftt/model/sapi/ApacheManager.java
@@ -508,7 +508,7 @@ public class ApacheManager extends 
AbstractManagedProcessesWebServerManager {
                EApacheVersion apache_version = decideApacheVersion(cm, host, 
build, this._apache_version);
                final String listen_address = "0.0.0.0";
                final int port = 80;
-               CouldConnect could = canConnect(listen_address, port); 
+               CouldConnect could = canConnect(listen_address, port, false); 
                if (could.connect) {
                        cm.println(EPrintType.CLUE, "ApacheManager", "A web 
server is already running");
                        cm.println(EPrintType.TIP, "ApacheManager", "Try `stop 
-c apache "+build.getBuildPath()+"` to stop Apache");
@@ -532,7 +532,7 @@ public class ApacheManager extends 
AbstractManagedProcessesWebServerManager {
                        cm.addGlobalException(EPrintType.CANT_CONTINUE, 
getClass(), "start", ex, "Unable to Start Apache after setup", prep.httpd, 
prep.apache_conf_file);
                        return false;
                }
-               if (canConnect(listen_address, port).connect) {
+               if (canConnect(listen_address, port, false).connect) {
                        cm.println(EPrintType.CLUE, "ApacheManager", "Apache 
running\nDocument Root: "+docroot+"\nURL: http://"+listen_address+":"+port+"/";);
                        return true;
                } else {
diff --git a/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java 
b/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java
index eb6d4e3..19b2dd0 100644
--- a/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java
+++ b/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java
@@ -34,6 +34,22 @@ public class BuiltinWebServerManager extends 
AbstractManagedProcessesWebServerMa
        }
        
        @Override
+       protected CouldConnect _canConnect(String listen_address, int port, 
boolean is_replacement) {
+               // process startup is slow (especially on Windows)
+               // and builtin_web is kind of buggy
+               // 
+               // give it extra time before we have to give up and try again 
(kill process and start another)start another process)
+               CouldConnect c = super._canConnect(listen_address, port, 
is_replacement);
+               if (c.connect)
+                       return c;
+               CouldConnect c2 = super._canConnect(listen_address, port, 
is_replacement);
+               if (c2.connect)
+                       return c2;
+               c.attempts += c2.attempts; // merge time and number of attempts 
from both for result-pack
+               return c;
+       }
+       
+       @Override
        protected ManagedProcessWebServerInstance 
createManagedProcessWebServerInstance(ConsoleManager cm, AHost host, 
ScenarioSet scenario_set, PhpBuild build, PhpIni ini, Map<String, String> env, 
String docroot, String listen_address, int port) {
                // run `php.exe -S listen_address:NNNN` in docroot
                String ini_dir;
diff --git a/src/com/mostc/pftt/model/sapi/IISManager.java 
b/src/com/mostc/pftt/model/sapi/IISManager.java
index bfdee9c..c10ba90 100644
--- a/src/com/mostc/pftt/model/sapi/IISManager.java
+++ b/src/com/mostc/pftt/model/sapi/IISManager.java
@@ -165,7 +165,7 @@ public class IISManager extends WebServerManager {
        }
        
        @Override
-       protected WebServerInstance createWebServerInstance(ConsoleManager cm, 
AHost host, ScenarioSet scenario_set, PhpBuild build, PhpIni ini, 
Map<String,String> env, String doc_root, boolean debugger_attached, Object 
server_name) {
+       protected WebServerInstance createWebServerInstance(ConsoleManager cm, 
AHost host, ScenarioSet scenario_set, PhpBuild build, PhpIni ini, 
Map<String,String> env, String doc_root, boolean debugger_attached, Object 
server_name, boolean is_replacement) {
                final String listen_address = host.getLocalhostListenAddress();
                final int listen_port = 80;
                
diff --git a/src/com/mostc/pftt/model/sapi/WebServerManager.java 
b/src/com/mostc/pftt/model/sapi/WebServerManager.java
index 65d8526..d1683a7 100644
--- a/src/com/mostc/pftt/model/sapi/WebServerManager.java
+++ b/src/com/mostc/pftt/model/sapi/WebServerManager.java
@@ -124,12 +124,12 @@ public abstract class WebServerManager extends 
SAPIManager {
                                }
                        }
                        
-                       assigned.replacement = sapi = 
createWebServerInstance(cm, host, scenario_set, build, ini, env, docroot, 
debugger_attached, server_name);
+                       assigned.replacement = sapi = 
createWebServerInstance(cm, host, scenario_set, build, ini, env, docroot, 
debugger_attached, server_name, true);
                        synchronized(assigned.active_test_cases) {
                                
sapi.active_test_cases.addAll(assigned.active_test_cases);
                        }
                } else {
-                       sapi = createWebServerInstance(cm, host, scenario_set, 
build, ini, env, docroot, debugger_attached, server_name);
+                       sapi = createWebServerInstance(cm, host, scenario_set, 
build, ini, env, docroot, debugger_attached, server_name, false);
                }
                if (sapi.isRunning()) {
                        synchronized(instances) {
@@ -155,7 +155,7 @@ public abstract class WebServerManager extends SAPIManager {
                return env;
        }
        
-       protected abstract WebServerInstance 
createWebServerInstance(ConsoleManager cm, AHost host, ScenarioSet 
scenario_set, PhpBuild build, PhpIni ini, Map<String,String> env, String 
docroot, boolean debugger_attached, Object server_name);
+       protected abstract WebServerInstance 
createWebServerInstance(ConsoleManager cm, AHost host, ScenarioSet 
scenario_set, PhpBuild build, PhpIni ini, Map<String,String> env, String 
docroot, boolean debugger_attached, Object server_name, boolean is_replacement);
        
        /** some web servers can only have one active instance at any one time
         * 
diff --git a/src/com/mostc/pftt/results/PhpUnitResultReader.java 
b/src/com/mostc/pftt/results/PhpUnitResultReader.java
index c72b4ac..38e32a4 100644
--- a/src/com/mostc/pftt/results/PhpUnitResultReader.java
+++ b/src/com/mostc/pftt/results/PhpUnitResultReader.java
@@ -170,12 +170,14 @@ public class PhpUnitResultReader extends 
AbstractPhpUnitRW {
 
        @Override
        public int count(EPhpUnitTestStatus status) {
-               return status_list_map.get(status).count;
+               StatusListEntry e = status_list_map.get(status);
+               return e==null ? 0 : e.count;
        }
 
        @Override
        public List<String> getTestNames(EPhpUnitTestStatus status) {
-               return status_list_map.get(status).test_names;
+               StatusListEntry e = status_list_map.get(status);
+               return e==null ? new java.util.ArrayList<String>(0) : 
e.test_names;
        }
 
        @Override
diff --git a/src/com/mostc/pftt/results/PhptResultWriter.java 
b/src/com/mostc/pftt/results/PhptResultWriter.java
index f75fb32..19a3533 100644
--- a/src/com/mostc/pftt/results/PhptResultWriter.java
+++ b/src/com/mostc/pftt/results/PhptResultWriter.java
@@ -148,7 +148,7 @@ public class PhptResultWriter extends AbstractPhptRW {
                for ( StatusListEntry e : status_list_map.values() )
                        e.close();
                
-               if (test_count==0) {
+               if (count==0) {
                        dir.delete();
                }
        } // end public void close

Reply via email to