Commit: 54a9a64e1ab154f9cbe8f318047c34c769212c8b Author: Matt Ficken <v-maf...@microsoft.com> Fri, 15 Feb 2013 15:53:27 -0800 Parents: 36873b54238ccf9aed2246724d8044835ce0c7ba Branches: master
Link: http://git.php.net/?p=pftt2.git;a=commitdiff;h=54a9a64e1ab154f9cbe8f318047c34c769212c8b Log: unstable phpunit support Former-commit-id: 764cd140765277890a848a0d6f8f83996155dc73 Changed paths: M conf/app/joomla.groovy M conf/symfony.groovy M src/com/mostc/pftt/main/Config.java M src/com/mostc/pftt/main/PfttMain.java M src/com/mostc/pftt/model/app/PhpUnitSourceTestPack.java M src/com/mostc/pftt/model/app/PhpUnitTestCase.java M src/com/mostc/pftt/model/core/PhptTestCase.java M src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java M src/com/mostc/pftt/model/sapi/ApacheManager.java M src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java M src/com/mostc/pftt/model/sapi/CrashedWebServerInstance.java M src/com/mostc/pftt/model/sapi/IISManager.java M src/com/mostc/pftt/model/sapi/WebServerInstance.java M src/com/mostc/pftt/model/sapi/WebServerManager.java M src/com/mostc/pftt/results/PhpResultPackWriter.java M src/com/mostc/pftt/results/PhpUnitTestResult.java M src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java M src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java M src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java M src/com/mostc/pftt/runner/AbstractTestCaseRunner.java M src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java M src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java M src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java M src/com/mostc/pftt/runner/LocalPhpUnitTestPackRunner.java M src/com/mostc/pftt/scenario/AbstractSAPIScenario.java M src/com/mostc/pftt/scenario/AbstractWebServerScenario.java M src/com/mostc/pftt/scenario/CLIScenario.java
diff --git a/conf/app/joomla.groovy b/conf/app/joomla.groovy index d2a277b..7742ac4 100644 --- a/conf/app/joomla.groovy +++ b/conf/app/joomla.groovy @@ -7,8 +7,49 @@ def scenarios() { /** Joomla-Platform != Joomla-CMS * * @see https://github.com/joomla/joomla-platform - * + * */ +class SymfonyPhpUnitTestPack extends PhpUnitSourceTestPack { + + @Override + public String getVersionString() { + return "Symfony-2.1.7"; + } + + @Override + public boolean open(ConsoleManager cm, AHost host) throws Exception { + // 1. + addBlacklist("vendor/kriswallsmith/assetic/tests/assetic/test/filter/sass/sassfiltertest.php"); + addBlacklist("vendor/sensio/generator-bundle/sensio/bundle/generatorbundle/resources/skeleton/bundle/defaultcontrollertest.php"); + addBlacklist("vendor/symfony/symfony/vendor/kriswallsmith/assetic/tests/assetic/test/filter/sass/sassfiltertest.php"); + addBlacklist("vendor/symfony/symfony/vendor/sensio/generator-bundle/sensio/bundle/generatorbundle/resources/skeleton/bundle/defaultcontrollertest.php"); + addBlacklist("vendor/symfony/symfony/vendor/twig/twig/test/twig/tests/integrationtest.php"); + addBlacklist("vendor/twig/twig/test/twig/tests/integrationtest.php"); + + // 2. + setRoot("C:\\php-sdk\\PFTT\\current\\cache\\working\\Symfony"); + //addPhpUnitDist(getRoot()+"/vendor/symfony/symfony/src", getRoot()+"/vendor/symfony/symfony/autoload.php.dist"); + //addPhpUnitDist(getRoot()+"/vendor/doctrine/common/tests", getRoot()+"/vendor/doctrine/common/tests/Doctrine/Tests/TestInit.php"); + addIncludeDirectory(getRoot()+"/vendor/symfony/symfony/src"); + + // 3. + if (!host.exists(getRoot()+"/vendor/symfony/symfony/vendor")) { + // copy Vendors, which is part of the Symfony install process + // + // + String tmp_dir = host.mktempname(getClass()); + // have to move to a temp directory because it'll cause a loop otherwise + host.copy(getRoot()+"/vendor", tmp_dir+"/vendor"); + + host.move(tmp_dir+"/vendor", getRoot()+"/vendor/symfony/symfony/vendor"); + + host.delete(tmp_dir); + } + + return true; + } // end public boolean open + +} // end class SymfonyPhpUnitTestPack class JoomlaPlatformPhpUnitTestPack extends SymfonyPhpUnitTestPack { @Override diff --git a/conf/symfony.groovy b/conf/symfony.groovy index af55cbb..eb067ab 100644 --- a/conf/symfony.groovy +++ b/conf/symfony.groovy @@ -45,7 +45,7 @@ class SymfonyPhpUnitTestPack extends PhpUnitSourceTestPack { } // end public boolean open } // end class SymfonyPhpUnitTestPack - +getBinding().setVariable("SymfonyPhpUnitTestPack", SymfonyPhpUnitTestPack); def getPhpUnitSourceTestPack() { // test symfony return new SymfonyPhpUnitTestPack(); diff --git a/src/com/mostc/pftt/main/Config.java b/src/com/mostc/pftt/main/Config.java index f79b10c..e5deba0 100644 --- a/src/com/mostc/pftt/main/Config.java +++ b/src/com/mostc/pftt/main/Config.java @@ -9,6 +9,8 @@ import java.util.List; import org.apache.commons.net.ftp.FTPClient; import org.codehaus.groovy.control.CompilationFailedException; +import org.codehaus.groovy.control.CompilerConfiguration; +import org.codehaus.groovy.control.customizers.ImportCustomizer; import org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack; import org.codehaus.groovy.runtime.metaclass.MissingPropertyExceptionNoStack; import org.columba.ristretto.smtp.SMTPProtocol; @@ -22,6 +24,7 @@ import com.mostc.pftt.results.ConsoleManager.EPrintType; import com.mostc.pftt.scenario.ApplicationScenario; import com.mostc.pftt.scenario.Scenario; import com.mostc.pftt.scenario.ScenarioSet; +import com.mostc.pftt.scenario.app.JoomlaScenario; import groovy.lang.GroovyClassLoader; import groovy.lang.GroovyObject; @@ -181,6 +184,13 @@ public final class Config { public static Config loadConfigFromFiles(ConsoleManager cm, File... files) throws CompilationFailedException, InstantiationException, IllegalAccessException, IOException { GroovyClassLoader loader = new GroovyClassLoader(Config.class.getClassLoader()); + /*ImportCustomizer ic = new ImportCustomizer(); + ic.addImports(""); + + CompilerConfiguration cc; + cc.addCompilationCustomizers(ic); + */ + Config config = new Config(); // don't load default scenarios. configuration file(s) completely replace them (not merged) @@ -190,7 +200,7 @@ public final class Config { GroovyObject go; Class<?> clazz; for (File file : files) { - clazz = loader.parseClass(importString(IOUtil.toString(new FileInputStream(file), IOUtil.QUARTER_MEGABYTE))); + clazz = loader.parseClass(importString(IOUtil.toString(new FileInputStream(file), IOUtil.QUARTER_MEGABYTE)), file.getAbsolutePath()); go = (GroovyObject) clazz.newInstance(); @@ -207,7 +217,7 @@ public final class Config { // import all standard Scenarios and Host types sb.append("import ");sb.append(PhpUnitSourceTestPack.class.getPackage().getName());sb.append(".*;\n"); sb.append("import ");sb.append(PhptTestCase.class.getPackage().getName());sb.append(".*;\n"); - sb.append("import ");sb.append(ApplicationScenario.class.getPackage().getName());sb.append(".*;\n"); + sb.append("import ");sb.append(JoomlaScenario.class.getPackage().getName());sb.append(".*;\n"); sb.append("import ");sb.append(Scenario.class.getPackage().getName());sb.append(".*;\n"); sb.append("import ");sb.append(AHost.class.getPackage().getName());sb.append(".*;\n"); sb.append("import ");sb.append(SMTPProtocol.class.getName());sb.append(";\n"); diff --git a/src/com/mostc/pftt/main/PfttMain.java b/src/com/mostc/pftt/main/PfttMain.java index 49af013..5b7eace 100644 --- a/src/com/mostc/pftt/main/PfttMain.java +++ b/src/com/mostc/pftt/main/PfttMain.java @@ -85,6 +85,11 @@ import com.mostc.pftt.util.WindowsSnapshotDownloadUtil.FindBuildTestPackPair; * */ +// TODO phpunit_list phpunit_all phpunit_named commands +// TODO change how ScenarioSets are permuted +// can have multiple database scenarios in 1 ScenarioSet for PHPTs +// can only have 1 for applications +// can only have 1 for PhpUnit // TODO phpt_all, etc... should display location of result-pack being written public class PfttMain { protected LocalHost host; @@ -791,24 +796,6 @@ public class PfttMain { System.out.println("PFTT: Config: no config files loaded... using defaults only ("+default_config_file+")"); } - // TODO - { - ScenarioSet scenario_set = config.getScenarioSets().get(0); - PhpBuild build = new PhpBuild("c:/php-sdk/php-5.5-ts-windows-vc9-x86-re6bde1f"); - build.open(cm, rt.host); - - PhpUnitSourceTestPack test_pack = config.getPhpUnitSourceTestPack(cm); - test_pack.open(cm, rt.host); // CRITICAL - - PhpResultPackWriter tmgr = new PhpResultPackWriter(rt.host, cm, new File(rt.host.getPhpSdkDir()), build, scenario_set); - LocalPhpUnitTestPackRunner r = new LocalPhpUnitTestPackRunner(cm, tmgr, scenario_set, build, rt.host, rt.host); - r.runAllTests(test_pack); - - tmgr.close(); - } // - - System.exit(0); - // // help user find/install WinDebug properly if ((cm.isDebugAll()||cm.isDebugList()) && rt.host.isWindows()) { @@ -824,7 +811,26 @@ public class PfttMain { // if (command!=null) { - if (command.equals("phpt_named")||command.equals("phptnamed")||command.equals("phptn")||command.equals("pn")) { + if (command.equals("phpunit_named")||command.equals("phpunitnamed")||command.equals("pun")) { + // TODO + } else if (command.equals("phpunit_list")||command.equals("phpunitist")||command.equals("pul")) { + // TODO + } else if (command.equals("phpunit_all")||command.equals("phpunitall")||command.equals("pua")) { + // TODO + ScenarioSet scenario_set = config.getScenarioSets().get(0); + // TODO + PhpBuild build = new PhpBuild("c:/php-sdk/php-5.5-ts-windows-vc9-x86-re6bde1f"); + build.open(cm, rt.host); + + PhpUnitSourceTestPack test_pack = config.getPhpUnitSourceTestPack(cm); + test_pack.open(cm, rt.host); // CRITICAL + + PhpResultPackWriter tmgr = new PhpResultPackWriter(rt.host, cm, new File(rt.host.getPhpSdkDir()), build, scenario_set); + LocalPhpUnitTestPackRunner r = new LocalPhpUnitTestPackRunner(cm, tmgr, scenario_set, build, rt.host, rt.host); + r.runAllTests(test_pack); + + tmgr.close(); + } else if (command.equals("phpt_named")||command.equals("phptnamed")||command.equals("phptn")||command.equals("pn")) { if (!(args.length > args_i+3)) { System.err.println("User Error: must specify build, test-pack and name(s) and/or name fragment(s)"); System.out.println("usage: pftt phpt_named <path to PHP build> <path to PHPT test-pack> <test case names or name fragments (separated by spaces)>"); diff --git a/src/com/mostc/pftt/model/app/PhpUnitSourceTestPack.java b/src/com/mostc/pftt/model/app/PhpUnitSourceTestPack.java index c433246..3d8ad89 100644 --- a/src/com/mostc/pftt/model/app/PhpUnitSourceTestPack.java +++ b/src/com/mostc/pftt/model/app/PhpUnitSourceTestPack.java @@ -197,15 +197,15 @@ public abstract class PhpUnitSourceTestPack implements SourceTestPack<PhpUnitAct } else if (file.getName().endsWith("Test.php")) { String file_name = Host.pathFrom(php_unit_dist.path.getAbsolutePath(), file.getAbsolutePath()); - String test_name = PhpUnitTestCase.normalizeFileName(file_name); + String test_file_name = PhpUnitTestCase.normalizeFileName(file_name); - if (blacklist_test_names.contains(test_name)) + if (blacklist_test_names.contains(test_file_name)) continue; - else if (!whitelist_test_names.isEmpty() && !whitelist_test_names.contains(test_name)) + else if (!whitelist_test_names.isEmpty() && !whitelist_test_names.contains(test_file_name)) continue; try { - readTestFile(php_unit_dist, test_cases, file); + readTestFile(test_file_name, php_unit_dist, test_cases, file); } catch ( QuercusParseException ex ) { ex.printStackTrace(); } @@ -216,12 +216,13 @@ public abstract class PhpUnitSourceTestPack implements SourceTestPack<PhpUnitAct /** reads PhpUnitTestCase(s) from given PHP file * + * @param test_file_name * @param php_unit_dist * @param test_cases * @param file * @throws IOException */ - protected void readTestFile(PhpUnitDist php_unit_dist, List<PhpUnitTestCase> test_cases, File file) throws IOException { + protected void readTestFile(String test_file_name, PhpUnitDist php_unit_dist, List<PhpUnitTestCase> test_cases, File file) throws IOException { FileInputStream fin = new FileInputStream(file); QuercusParser p = new QuercusParser(qctx, new FilePath(file.getAbsolutePath()), new ReadStream(new FileReadStream(fin))); QuercusProgram prog = p.parse(); @@ -239,7 +240,7 @@ public abstract class PhpUnitSourceTestPack implements SourceTestPack<PhpUnitAct // this is a test case test_cases.add(new PhpUnitTestCase( php_unit_dist, - file.getAbsolutePath(), + test_file_name, // some PhpUnits use the namespace keyword and/or \\ in the class name (namespaces) // InterpretedclassDef#getName will provide the absolute class name (including namespace) // in such cases, so nothing special needs to be done here for them diff --git a/src/com/mostc/pftt/model/app/PhpUnitTestCase.java b/src/com/mostc/pftt/model/app/PhpUnitTestCase.java index 0419102..48b852c 100644 --- a/src/com/mostc/pftt/model/app/PhpUnitTestCase.java +++ b/src/com/mostc/pftt/model/app/PhpUnitTestCase.java @@ -39,7 +39,7 @@ public class PhpUnitTestCase extends TestCase { public String toString() { return getName(); } - + public static String normalizeFileName(String test_name) { return Host.toUnixPath(test_name).toLowerCase(); } diff --git a/src/com/mostc/pftt/model/core/PhptTestCase.java b/src/com/mostc/pftt/model/core/PhptTestCase.java index f4cdfdd..1efbbcd 100644 --- a/src/com/mostc/pftt/model/core/PhptTestCase.java +++ b/src/com/mostc/pftt/model/core/PhptTestCase.java @@ -42,6 +42,10 @@ import com.mostc.pftt.util.apache.regexp.REProgram; * * A PHPT test may be 'borked' (not runnable) or unsupported. This can be marked as such without bothering to run them at all. * + * A PHPT can check $_ENV['PFTT_IS'] to tell if its running under PFTT. + * A PHPT can check $_ENV['PFTT_SCENARIO_SET'] to tell what scenarios its running under + * + * * @see #hasBorkInfo() * @see #hasUnsupportedInfo() * @see EPhptTestStatus diff --git a/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java b/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java index 51321b6..171bc81 100644 --- a/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java +++ b/src/com/mostc/pftt/model/sapi/AbstractManagedProcessesWebServerManager.java @@ -14,6 +14,7 @@ import com.mostc.pftt.host.AHost.ExecHandle; import com.mostc.pftt.model.core.PhpBuild; import com.mostc.pftt.model.core.PhpIni; import com.mostc.pftt.results.ConsoleManager; +import com.mostc.pftt.scenario.ScenarioSet; import com.mostc.pftt.util.DebuggerManager; import com.mostc.pftt.util.DebuggerManager.Debugger; import com.mostc.pftt.util.ErrorUtil; @@ -52,7 +53,7 @@ public abstract class AbstractManagedProcessesWebServerManager extends WebServer } @Override - protected WebServerInstance createWebServerInstance(ConsoleManager cm, AHost host, 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) { String sapi_output = ""; int port_attempts; boolean found_port; @@ -91,7 +92,7 @@ public abstract class AbstractManagedProcessesWebServerManager extends WebServer AHost.ExecHandle handle = null; try { // provide a ManagedProcessWebServerInstance to handle the running web server instance - final ManagedProcessWebServerInstance web = createManagedProcessWebServerInstance(cm, host, build, ini, env, docroot, listen_address, port); + final ManagedProcessWebServerInstance web = createManagedProcessWebServerInstance(cm, host, scenario_set, build, ini, env, docroot, listen_address, port); if (web==null) break; // fall through to returning CrashedWebServerInstance @@ -180,22 +181,29 @@ public abstract class AbstractManagedProcessesWebServerManager extends WebServer return new CrashedWebServerInstance(this, ini, env, sapi_output); } // end protected WebServerInstance createWebServerInstance - protected abstract ManagedProcessWebServerInstance createManagedProcessWebServerInstance(ConsoleManager cm, AHost host, PhpBuild build, PhpIni ini, Map<String, String> env, String docroot, String listen_address, int port); + 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 { protected Debugger debug_handle; protected final int port; protected final String hostname, cmd; + protected final String docroot; protected ExecHandle process; - public ManagedProcessWebServerInstance(AbstractManagedProcessesWebServerManager ws_mgr, String cmd, PhpIni ini, Map<String,String> env, String hostname, int port) { + public ManagedProcessWebServerInstance(AbstractManagedProcessesWebServerManager ws_mgr, String docroot, String cmd, PhpIni ini, Map<String,String> env, String hostname, int port) { super(ws_mgr, LocalHost.splitCmdString(cmd), ini, env); + this.docroot = docroot; this.cmd = cmd; this.hostname = hostname; this.port = port; } @Override + public String getDocroot() { + return docroot; + } + + @Override public String toString() { return hostname+":"+port; } @@ -230,6 +238,7 @@ public abstract class AbstractManagedProcessesWebServerManager extends WebServer @Override protected void do_close() { + //new IllegalStateException("do_close").printStackTrace(); if (debug_handle!=null)// && debug_handle.isRunning()) return; // TODO @@ -241,6 +250,7 @@ public abstract class AbstractManagedProcessesWebServerManager extends WebServer //if (debug_handle!=null) //debug_handle.close(); + // TODO why is #do_close called so much?? process.close(); //}}, 5000); } diff --git a/src/com/mostc/pftt/model/sapi/ApacheManager.java b/src/com/mostc/pftt/model/sapi/ApacheManager.java index 3fa09d8..9edd0e0 100644 --- a/src/com/mostc/pftt/model/sapi/ApacheManager.java +++ b/src/com/mostc/pftt/model/sapi/ApacheManager.java @@ -2,7 +2,6 @@ package com.mostc.pftt.model.sapi; import java.io.IOException; import java.lang.ref.WeakReference; -import java.util.HashMap; import java.util.Map; import javax.annotation.concurrent.ThreadSafe; @@ -59,14 +58,14 @@ public class ApacheManager extends AbstractManagedProcessesWebServerManager { try { if (!host.isWindows()) return true; - String os = apache_dir + "\\bin\\openssl.exe"; - if (!host.exists(os)) { + final String openssl_exe = apache_dir + "\\bin\\openssl.exe"; + if (!host.exists(openssl_exe)) { // can't check cm.println(EPrintType.SKIP_OPTIONAL, ApacheManager.class, "Can't find OpenSSL.exe (can't check OpenSSL version, assuming its ok)"); return true; } - ExecOutput eo = host.execOut("\""+os+"\" version", Host.ONE_MINUTE); + ExecOutput eo = host.execOut("\""+openssl_exe+"\" version", Host.ONE_MINUTE); return build.checkOpenSSLVersion(eo.output); } catch ( Exception ex ) { @@ -136,7 +135,7 @@ public class ApacheManager extends AbstractManagedProcessesWebServerManager { private Host cache_host; private String cache_httpd; @Override - protected ManagedProcessWebServerInstance createManagedProcessWebServerInstance(ConsoleManager cm, AHost host, PhpBuild build, PhpIni ini, Map<String, String> env, final String docroot, String listen_address, int port) { + protected ManagedProcessWebServerInstance createManagedProcessWebServerInstance(ConsoleManager cm, AHost host, ScenarioSet scenario_set, PhpBuild build, PhpIni ini, Map<String, String> env, final String docroot, String listen_address, int port) { EApacheVersion apache_version = decideApacheVersion(cm, host, build, this._apache_version); String httpd = httpd(apache_version, host); @@ -197,7 +196,9 @@ public class ApacheManager extends AbstractManagedProcessesWebServerManager { } // CRITICAL: must add extension dir (and fix path) AND it MUST end with \ (Windows) or / (Linux) - if (StringUtil.isEmpty(ini.getExtensionDir())) + if (ini==null) + ini = new PhpIni(); + else if (StringUtil.isEmpty(ini.getExtensionDir())) ini.setExtensionDir(host.fixPath(build.getDefaultExtensionDir())+host.dirSeparator()); else if (!ini.getExtensionDir().endsWith(host.dirSeparator())) // extension dir already set, but doesn't end with / or \ @@ -208,13 +209,7 @@ public class ApacheManager extends AbstractManagedProcessesWebServerManager { final String apache_conf_file = host.joinIntoOnePath(conf_dir, "httpd.conf"); final String error_log = host.joinIntoOnePath(conf_dir, "error.log"); - if (env==null) - env = new HashMap<String,String>(2); - // tell apache mod_php where to find php.ini - env.put("PHPRC", php_conf_file); - // these 2 env vars are needed for some phpts - env.put("TEST_PHP_EXECUTABLE", httpd); - env.put("TEST_PHP_CGI_EXECUTABLE", build.getPhpCgiExe()); + env = prepareENV(env, php_conf_file, build, scenario_set, httpd); // apache configuration (also tells where to find php.ini. see PHPIniDir directive) String conf_str = writeConfigurationFile(apache_version, host, dll, conf_dir, error_log, listen_address, port, docroot); @@ -235,7 +230,7 @@ public class ApacheManager extends AbstractManagedProcessesWebServerManager { final String cmdline = httpd+" -X -f "+host.fixPath(apache_conf_file); // @see #createWebServerInstance for where command is executed to create httpd.exe process - return new ApacheWebServerInstance(apache_version, this, cmdline, ini, env, listen_address, port, host, conf_dir, apache_conf_file, error_log); + return new ApacheWebServerInstance(apache_version, this, docroot, cmdline, ini, env, listen_address, port, host, conf_dir, apache_conf_file, error_log); } // end protected ManagedProcessWebServerInstance createManagedProcessWebServerInstance public class ApacheWebServerInstance extends ManagedProcessWebServerInstance { @@ -244,8 +239,8 @@ public class ApacheManager extends AbstractManagedProcessesWebServerManager { protected final EApacheVersion apache_version; protected WeakReference<String> log_ref; - public ApacheWebServerInstance(EApacheVersion apache_version, ApacheManager ws_mgr, String cmd, PhpIni ini, Map<String,String> env, String hostname, int port, AHost host, String conf_dir, String apache_conf_file, String error_log) { - super(ws_mgr, cmd, ini, env, hostname, port); + public ApacheWebServerInstance(EApacheVersion apache_version, ApacheManager ws_mgr, String docroot, String cmd, PhpIni ini, Map<String,String> env, String hostname, int port, AHost host, String conf_dir, String apache_conf_file, String error_log) { + super(ws_mgr, docroot, cmd, ini, env, hostname, port); this.apache_version = apache_version; this.host = host; this.conf_dir = conf_dir; diff --git a/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java b/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java index 8f70175..bb852b8 100644 --- a/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java +++ b/src/com/mostc/pftt/model/sapi/BuiltinWebServerManager.java @@ -11,6 +11,7 @@ import com.mostc.pftt.model.core.PhpBuild; import com.mostc.pftt.model.core.PhpIni; import com.mostc.pftt.results.ConsoleManager; import com.mostc.pftt.results.ConsoleManager.EPrintType; +import com.mostc.pftt.scenario.ScenarioSet; /** manages local instances of PHP's builtin web server * @@ -30,18 +31,21 @@ public class BuiltinWebServerManager extends AbstractManagedProcessesWebServerMa } @Override - protected ManagedProcessWebServerInstance createManagedProcessWebServerInstance(ConsoleManager cm, AHost host, PhpBuild build, PhpIni ini, Map<String, String> env, String docroot, String listen_address, int port) { + 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 // TODO ensureDefault(); - return new BuiltinWebServerInstance(this, host, build, build.getPhpExe()+" -S "+listen_address+":"+port+" "+(ini==null?"":ini.toCliArgString(host)), ini, env, listen_address, port); + + // TODO env = prepareENV(env, php_conf_file, build, scenario_set, httpd); + + return new BuiltinWebServerInstance(this, host, build, docroot, build.getPhpExe()+" -S "+listen_address+":"+port+" "+(ini==null?"":ini.toCliArgString(host)), ini, env, listen_address, port); } public class BuiltinWebServerInstance extends ManagedProcessWebServerInstance { protected final PhpBuild build; protected final AHost host; - public BuiltinWebServerInstance(BuiltinWebServerManager ws_mgr, AHost host, PhpBuild build, String cmd, PhpIni ini, Map<String,String> env, String hostname, int port) { - super(ws_mgr, cmd, ini, env, hostname, port); + public BuiltinWebServerInstance(BuiltinWebServerManager ws_mgr, AHost host, PhpBuild build, String docroot, String cmd, PhpIni ini, Map<String,String> env, String hostname, int port) { + super(ws_mgr, docroot, cmd, ini, env, hostname, port); this.host = host; this.build = build; } diff --git a/src/com/mostc/pftt/model/sapi/CrashedWebServerInstance.java b/src/com/mostc/pftt/model/sapi/CrashedWebServerInstance.java index 74ad6dd..43e9c82 100644 --- a/src/com/mostc/pftt/model/sapi/CrashedWebServerInstance.java +++ b/src/com/mostc/pftt/model/sapi/CrashedWebServerInstance.java @@ -77,4 +77,10 @@ public class CrashedWebServerInstance extends WebServerInstance { return false; } + @Override + public String getDocroot() { + // TODO Auto-generated method stub + return null; + } + } diff --git a/src/com/mostc/pftt/model/sapi/IISManager.java b/src/com/mostc/pftt/model/sapi/IISManager.java index d1d13fa..ad2ba5b 100644 --- a/src/com/mostc/pftt/model/sapi/IISManager.java +++ b/src/com/mostc/pftt/model/sapi/IISManager.java @@ -12,6 +12,7 @@ import com.mostc.pftt.model.core.PhpBuild; import com.mostc.pftt.model.core.PhpIni; import com.mostc.pftt.results.ConsoleManager; import com.mostc.pftt.results.ConsoleManager.EPrintType; +import com.mostc.pftt.scenario.ScenarioSet; import com.mostc.pftt.util.ErrorUtil; /** manages and monitors IIS and IIS express web servers @@ -82,6 +83,8 @@ public class IISManager extends WebServerManager { String php_binary = build.getPhpCgiExe(); String c_section = "section:system.webServer"; + + // TODO env = prepareENV(env, php_conf_file, build, scenario_set, httpd); try { ExecOutput eo; @@ -155,14 +158,14 @@ public class IISManager extends WebServerManager { WebServerInstance wsi; @Override - public synchronized WebServerInstance getWebServerInstance(ConsoleManager cm, AHost host, PhpBuild build, PhpIni ini, Map<String,String> env, String docroot, WebServerInstance assigned, boolean debugger_attached, Object server_name) { + public synchronized WebServerInstance getWebServerInstance(ConsoleManager cm, AHost host, ScenarioSet scenario_set, PhpBuild build, PhpIni ini, Map<String,String> env, String docroot, WebServerInstance assigned, boolean debugger_attached, Object server_name) { if (wsi==null) - wsi = super.getWebServerInstance(cm, host, build, ini, env, docroot, assigned, debugger_attached, server_name); + wsi = super.getWebServerInstance(cm, host, scenario_set, build, ini, env, docroot, assigned, debugger_attached, server_name); return wsi; } @Override - protected WebServerInstance createWebServerInstance(ConsoleManager cm, AHost host, 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) { final String listen_address = host.getLocalhostListenAddress(); final int listen_port = 80; @@ -262,6 +265,12 @@ public class IISManager extends WebServerManager { // TODO Auto-generated method stub return false; } + + @Override + public String getDocroot() { + // TODO Auto-generated method stub + return null; + } } // end public class IISWebServerInstance diff --git a/src/com/mostc/pftt/model/sapi/WebServerInstance.java b/src/com/mostc/pftt/model/sapi/WebServerInstance.java index adbfa6a..7b3b3a1 100644 --- a/src/com/mostc/pftt/model/sapi/WebServerInstance.java +++ b/src/com/mostc/pftt/model/sapi/WebServerInstance.java @@ -215,5 +215,7 @@ public abstract class WebServerInstance extends SAPIInstance { } protected abstract void do_close(); + + public abstract String getDocroot(); } // end public abstract class WebServerInstance diff --git a/src/com/mostc/pftt/model/sapi/WebServerManager.java b/src/com/mostc/pftt/model/sapi/WebServerManager.java index 681cf3d..e1b769a 100644 --- a/src/com/mostc/pftt/model/sapi/WebServerManager.java +++ b/src/com/mostc/pftt/model/sapi/WebServerManager.java @@ -3,6 +3,7 @@ package com.mostc.pftt.model.sapi; import java.io.IOException; import java.net.Socket; import java.util.ArrayList; +import java.util.HashMap; import java.util.Map; import javax.annotation.concurrent.ThreadSafe; @@ -12,6 +13,8 @@ import com.mostc.pftt.host.Host; import com.mostc.pftt.model.core.PhpBuild; import com.mostc.pftt.model.core.PhpIni; import com.mostc.pftt.results.ConsoleManager; +import com.mostc.pftt.runner.AbstractPhptTestCaseRunner; +import com.mostc.pftt.scenario.ScenarioSet; /** Manages a certain type of web server, such as PHP's builtin web server. * @@ -77,6 +80,7 @@ public abstract class WebServerManager extends SAPIManager { * * @param cm * @param host + * @param scenario_set * @param build * @param ini * @param env @@ -88,7 +92,7 @@ public abstract class WebServerManager extends SAPIManager { * @see WebServerInstance#isDebuggerAttached * @return */ - public WebServerInstance getWebServerInstance(ConsoleManager cm, AHost host, PhpBuild build, PhpIni ini, Map<String,String> env, final String docroot, WebServerInstance assigned, boolean debugger_attached, Object server_name) { + public WebServerInstance getWebServerInstance(ConsoleManager cm, AHost host, ScenarioSet scenario_set, PhpBuild build, PhpIni ini, Map<String,String> env, final String docroot, WebServerInstance assigned, boolean debugger_attached, Object server_name) { WebServerInstance sapi; if (assigned!=null) { if (assigned.isRunning() && (!debugger_attached||assigned.isDebuggerAttached())) @@ -103,12 +107,12 @@ public abstract class WebServerManager extends SAPIManager { } } - assigned.replacement = sapi = createWebServerInstance(cm, host, build, ini, env, docroot, debugger_attached, server_name); + assigned.replacement = sapi = createWebServerInstance(cm, host, scenario_set, build, ini, env, docroot, debugger_attached, server_name); synchronized(assigned.active_test_cases) { sapi.active_test_cases.addAll(assigned.active_test_cases); } } else { - sapi = createWebServerInstance(cm, host, build, ini, env, docroot, debugger_attached, server_name); + sapi = createWebServerInstance(cm, host, scenario_set, build, ini, env, docroot, debugger_attached, server_name); } if (sapi.isRunning()) { synchronized(instances) { @@ -118,7 +122,21 @@ public abstract class WebServerManager extends SAPIManager { return sapi; } - protected abstract WebServerInstance createWebServerInstance(ConsoleManager cm, AHost host, PhpBuild build, PhpIni ini, Map<String,String> env, String docroot, boolean debugger_attached, Object server_name); + protected Map<String,String> prepareENV(Map<String,String> env, String php_conf_file, PhpBuild build, ScenarioSet scenario_set, String httpd_exe) { + if (env==null) + env = new HashMap<String,String>(2); + // tell apache mod_php where to find php.ini + env.put(AbstractPhptTestCaseRunner.ENV_PHPRC, php_conf_file); + // these 2 env vars are needed for some phpts + env.put(AbstractPhptTestCaseRunner.ENV_TEST_PHP_EXECUTABLE, httpd_exe); + env.put(AbstractPhptTestCaseRunner.ENV_TEST_PHP_CGI_EXECUTABLE, build.getPhpCgiExe()); + // + env.put(AbstractPhptTestCaseRunner.ENV_PFTT_SCENARIO_SET, scenario_set.getNameWithVersionInfo()); + env.put(AbstractPhptTestCaseRunner.ENV_PFTT_IS, "1"); + 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); /** some web servers can only have one active instance at any one time * diff --git a/src/com/mostc/pftt/results/PhpResultPackWriter.java b/src/com/mostc/pftt/results/PhpResultPackWriter.java index 2f1a671..b215174 100644 --- a/src/com/mostc/pftt/results/PhpResultPackWriter.java +++ b/src/com/mostc/pftt/results/PhpResultPackWriter.java @@ -81,11 +81,6 @@ public class PhpResultPackWriter extends PhpResultPack implements ITestResultRec phpt_writer_map = new HashMap<AHost,HashMap<ScenarioSet,PhptResultWriter>>(16); phpunit_writer_map = new HashMap<AHost,HashMap<ScenarioSet,PhpUnitResultWriter>>(16); - // setup serializer to indent XML (pretty print) so its easy for people to read - //serial = new KXmlSerializer(); - // TODO serial.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); - // - cm.w = this; this.local_host = local_host; diff --git a/src/com/mostc/pftt/results/PhpUnitTestResult.java b/src/com/mostc/pftt/results/PhpUnitTestResult.java index ceb1115..423db85 100644 --- a/src/com/mostc/pftt/results/PhpUnitTestResult.java +++ b/src/com/mostc/pftt/results/PhpUnitTestResult.java @@ -65,6 +65,8 @@ public class PhpUnitTestResult { serial.text(output); serial.endTag(null, "failure"); break; + default: + break; } serial.endTag(null, "testcase"); } // end public void serial diff --git a/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java b/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java index 42410ac..2042a4c 100644 --- a/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java +++ b/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java @@ -14,9 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import com.mostc.pftt.host.AHost; -import com.mostc.pftt.host.LocalHost; import com.mostc.pftt.host.RemoteHost; -import com.mostc.pftt.host.SSHHost; import com.mostc.pftt.model.ActiveTestPack; import com.mostc.pftt.model.SourceTestPack; import com.mostc.pftt.model.TestCase; @@ -28,11 +26,10 @@ import com.mostc.pftt.model.sapi.WebServerInstance; import com.mostc.pftt.results.ConsoleManager; import com.mostc.pftt.results.ITestResultReceiver; import com.mostc.pftt.results.ConsoleManager.EPrintType; +import com.mostc.pftt.runner.LocalPhpUnitTestPackRunner.PhpUnitThread; import com.mostc.pftt.scenario.AbstractFileSystemScenario; import com.mostc.pftt.scenario.AbstractSAPIScenario; import com.mostc.pftt.scenario.AbstractWebServerScenario; -import com.mostc.pftt.scenario.SMBDFSScenario; -import com.mostc.pftt.scenario.SMBDeduplicationScenario; import com.mostc.pftt.scenario.Scenario; import com.mostc.pftt.scenario.ScenarioSet; import com.mostc.pftt.scenario.AbstractFileSystemScenario.ITestPackStorageDir; @@ -94,15 +91,6 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex this.twriter = twriter; runner_state = new AtomicReference<ETestPackRunnerState>(); - - //storage_host = new LocalHost(); - /* - SSHHost remote_host = new SSHHost("J-2012sp0", "administrator", "password01!"); - this.storage_host = remote_host; // for LocalPhptTestPackRunner#setupStorageDir - // TODO - //file_scenario = new SMBDeduplicationScenario(remote_host, "B:"); - file_scenario = new SMBDFSScenario(remote_host); - */ } public void runTestList(S test_pack, List<T> test_cases) throws Exception { @@ -129,7 +117,7 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex runner_state.set(ETestPackRunnerState.RUNNING); sapi_scenario = AbstractSAPIScenario.getSAPIScenario(scenario_set); - if (file_scenario==null) // TODO temp allow file_scenario to be set in <init> and don't override it + if (file_scenario==null) file_scenario = AbstractFileSystemScenario.getFileSystemScenario(scenario_set); if (storage_host instanceof RemoteHost) { @@ -244,10 +232,10 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex // @see -no_nts console option- if used, all test cases should go to #handleTS // if -no_nts not used, see if #handleNTS wants to handle them - // TODO if (!cm.isThreadSafety() || !handleNTS(group_key, test_case)) { + if (!cm.isThreadSafety() || !handleNTS(group_key, test_case)) { // test case is thread-safe or we're ignoring thread-safety (-no_nts) handleTS(thread_safe_list, group_key, test_case); - // TODO } + } // } // end while @@ -354,25 +342,24 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex } - protected void executeTestCases(boolean parallel) throws InterruptedException { + protected void executeTestCases(boolean parallel) throws InterruptedException, IllegalStateException, IOException { // decide number of threads // 1. ask SAPI Scenario // 2. limit to number of thread safe tests + number of NTS extensions (extensions with NTS tests) // -exceed this number and there will be threads that won't have any tests to run - // 3. limit to MAX_THREAD_COUNT - // 4. if debugging + // 3. if debugging + // 4. limit to MAX_THREAD_COUNT int thread_count = sapi_scenario.getTestThreadCount(runner_host); if (thread_count > thread_safe_test_count + non_thread_safe_exts.size()) thread_count = thread_safe_test_count + non_thread_safe_exts.size(); - if (thread_count > MAX_THREAD_COUNT) - thread_count = MAX_THREAD_COUNT; - thread_count = 16; // TODO if (cm.isDebugAll()) { // run fewer threads b/c we're running WinDebug // (can run WinDebug w/ same number of threads, but UI responsiveness will be SLoow) thread_count = Math.max(1, thread_count / 2); } + if (thread_count > MAX_THREAD_COUNT) + thread_count = MAX_THREAD_COUNT; cm.println(EPrintType.IN_PROGRESS, getClass(), "Starting up Test Threads: thread_count="+thread_count+" runner_host="+runner_host+" sapi_scenario="+sapi_scenario); test_count = new AtomicInteger(0); @@ -390,7 +377,7 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex int c ; while ( ( c = active_thread_count.get() ) > 0 ) { Thread.sleep(c>3?1000:50); } } // end protected void executeTestCases - protected void start_thread(boolean parallel) { + protected void start_thread(boolean parallel) throws IllegalStateException, IOException { TestPackThread<T> t = createTestPackThread(parallel); // if running Swing UI, run thread minimum priority in favor of Swing EDT t.setPriority(Thread.MIN_PRIORITY); @@ -398,7 +385,7 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex t.start(); } - protected abstract TestPackThread<T> createTestPackThread(boolean parallel); + protected abstract TestPackThread<T> createTestPackThread(boolean parallel) throws IllegalStateException, IOException; public abstract class TestPackThread<t extends T> extends SlowReplacementTestPackRunnerThread { protected final AtomicBoolean run_thread; protected final boolean parallel; @@ -497,15 +484,17 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex if (sapi_scenario instanceof AbstractWebServerScenario) { // TODO temp //SAPIInstance sa = ((SharedSAPIInstanceTestCaseGroupKey)group_key).getSAPIInstance(); - if (sa==null||sa.isCrashed()||(debugger_attached && !((WebServerInstance)sa).isDebuggerAttached())) { + if (sa==null||sa.isCrashed()) { // TODO ||(debugger_attached && !((WebServerInstance)sa).isDebuggerAttached())) { //((SharedSAPIInstanceTestCaseGroupKey)group_key).setSAPIInstance( - sa = ((AbstractWebServerScenario)sapi_scenario).smgr.getWebServerInstance(cm, runner_host, build, group_key.getPhpIni(), group_key.getEnv(), - active_test_pack==null?null: // TODO phpunit + sa = ((AbstractWebServerScenario)sapi_scenario).smgr.getWebServerInstance(cm, runner_host, scenario_set, build, group_key.getPhpIni(), + group_key.getEnv(), this instanceof PhpUnitThread ? ((PhpUnitThread)this).my_temp_dir // TODO temp phpunit + : active_test_pack.getStorageDirectory(), (WebServerInstance) sa, debugger_attached, completed_tests); //); // TODO don't store sa on group_key! (don't share sa between threads) + // important: this closes sa ((SharedSAPIInstanceTestCaseGroupKey)group_key).setSAPIInstance(cm, runner_host, sa); // TODO temp } } @@ -522,6 +511,7 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex // CRITICAL: catch exception to record with test try { runTest(group_key, test_case); + // TODO -delay_between_ms console option Thread.sleep(1000000); } catch ( Throwable ex ) { twriter.addTestException(storage_host, scenario_set, test_case, ex, sa); } @@ -531,6 +521,11 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex Thread.yield(); } // end while } finally { + if (sa!=null) { + sa.close(); // TODO + sa = null; + } + if (parallel) { // @see HttpTestCaseRunner#http_execute which calls #notifyCrash // make sure a WebServerInstance is still running here, so it will be shared with each @@ -553,7 +548,11 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex @Override protected void createNewThread() { + try { start_thread(parallel); + } catch ( Exception ex ) { + ex.printStackTrace(); + } } @Override diff --git a/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java b/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java index 3966671..bad1914 100644 --- a/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java +++ b/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java @@ -68,10 +68,11 @@ public abstract class AbstractPhpUnitTestCaseRunner extends AbstractTestCaseRunn this.include_files = include_files; } - protected static Pattern PAT_CLASS_NOT_FOUND, PAT_SYNTAX_ERROR, PAT_FATAL_ERROR; + protected static Pattern PAT_CLASS_NOT_FOUND, PAT_REQUIRE_ONCE_FAIL, PAT_SYNTAX_ERROR, PAT_FATAL_ERROR; static { - PAT_CLASS_NOT_FOUND = Pattern.compile(".*Fatal error: Class '.*' not found.*"); - PAT_FATAL_ERROR = Pattern.compile(".*Fatal error: .*"); + PAT_CLASS_NOT_FOUND = Pattern.compile(".*Fatal error.*Class '.*' not found.*"); + PAT_REQUIRE_ONCE_FAIL = Pattern.compile(".*Fatal error.*require_once.*Failed opening required.*"); + PAT_FATAL_ERROR = Pattern.compile(".*Fatal error.*"); PAT_SYNTAX_ERROR = Pattern.compile(".*No syntax errors detected.*"); } @@ -113,19 +114,29 @@ public abstract class AbstractPhpUnitTestCaseRunner extends AbstractTestCaseRunn final String template_file = my_temp_dir+"/test.php"; - host.saveTextFile(template_file, generatePhpScript()); + final String php_script = generatePhpScript(); + host.saveTextFile(template_file, php_script); + final String output = execute(template_file); // show output from all on console for debugging if (cm.isPfttDebug()) { - System.err.println(test_case.getName()+":"); - System.err.println(output); + synchronized(System.err) { + System.err.println(test_case.getName()+":"); + System.err.println(php_script); + System.err.println(test_case.getName()+":"); + System.err.println(output); + } } // - + EPhpUnitTestStatus status; - if (is_crashed) { + if (PAT_REQUIRE_ONCE_FAIL.matcher(output).find() || output.contains("404 Not Found")) { // TODO only check 404 w/ Http + status = EPhpUnitTestStatus.TEST_EXCEPTION; + + tmgr.addResult(host, scenario_set, new PhpUnitTestResult(test_case, status, scenario_set, host, output)); + } else if (is_crashed) { if (PAT_CLASS_NOT_FOUND.matcher(output).find()) { status = EPhpUnitTestStatus.UNSUPPORTED; @@ -159,10 +170,20 @@ public abstract class AbstractPhpUnitTestCaseRunner extends AbstractTestCaseRunn // read status code if (status_str.length() > 0) { - status = EPhpUnitTestStatus.valueOf(status_str); + status = null; + for ( EPhpUnitTestStatus s : EPhpUnitTestStatus.values()) { + if (status_str.equals(s.toString())) { + status = s; + break; + } + } - if (status==null) - status = EPhpUnitTestStatus.BORK; + if (status==null) { + if (output.contains("Fatal Error")) + status = EPhpUnitTestStatus.ERROR; + else + status = EPhpUnitTestStatus.FAILURE; + } } else { // if test had a 'Fatal Error', it might not have been able to print the status code at all // (otherwise it should always have a status code) diff --git a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java index d6e8985..934a735 100644 --- a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java +++ b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner.java @@ -16,6 +16,7 @@ import com.mostc.pftt.results.PhptTestResult; import com.mostc.pftt.scenario.ScenarioSet; public abstract class AbstractPhptTestCaseRunner extends AbstractTestCaseRunner { + public static final String ENV_PHPRC = "PHPRC"; public static final String ENV_SCRIPT_FILENAME = "SCRIPT_FILENAME"; public static final String ENV_PATH_TRANSLATED = "PATH_TRANSLATED"; public static final String ENV_TEST_PHP_EXECUTABLE = "TEST_PHP_EXECUTABLE"; diff --git a/src/com/mostc/pftt/runner/AbstractTestCaseRunner.java b/src/com/mostc/pftt/runner/AbstractTestCaseRunner.java index f66592c..ce946f4 100644 --- a/src/com/mostc/pftt/runner/AbstractTestCaseRunner.java +++ b/src/com/mostc/pftt/runner/AbstractTestCaseRunner.java @@ -1,6 +1,11 @@ package com.mostc.pftt.runner; public abstract class AbstractTestCaseRunner { + /** PFTT extension: this ENV var provides the ScenarioSet PFTT is running */ + public static final String ENV_PFTT_SCENARIO_SET = "PFTT_SCENARIO_SET"; + /** PFTT extension: tells test case its running under PFTT instead of run-test.php or phpunit */ + public static final String ENV_PFTT_IS = "PFTT_IS"; + /** returns output from SAPI (ex: Web Server) used to run the test, * if it crashed. if SAPI did not crash, returns null. * diff --git a/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java b/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java index c030763..392e60d 100644 --- a/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java +++ b/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java @@ -252,8 +252,10 @@ public class CliPhptTestCaseRunner extends AbstractPhptTestCaseRunner2 { if (build.hasPhpCgiExe()) env.put(ENV_TEST_PHP_CGI_EXECUTABLE, build.getPhpCgiExe()); + // + env.put(ENV_PFTT_SCENARIO_SET, scenario_set.getNameWithVersionInfo()); + env.put(AbstractPhptTestCaseRunner.ENV_PFTT_IS, "1"); - //env.put(ENV_CONTENT_TYPE, "application/x-www-form-urlencoded"); prepareSTDIN(); createShellScript(); diff --git a/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java b/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java index 6e1c0e8..e877d6c 100644 --- a/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java +++ b/src/com/mostc/pftt/runner/HttpPhpUnitTestCaseRunner.java @@ -1,6 +1,7 @@ package com.mostc.pftt.runner; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.net.Socket; import java.util.Map; @@ -29,7 +30,6 @@ import com.mostc.pftt.results.ITestResultReceiver; import com.mostc.pftt.scenario.ScenarioSet; import com.mostc.pftt.util.ErrorUtil; -// TODO intl extension not available public class HttpPhpUnitTestCaseRunner extends AbstractPhpUnitTestCaseRunner { protected final WebServerManager smgr; protected final ByteArrayOutputStream response_bytes; @@ -60,16 +60,19 @@ public class HttpPhpUnitTestCaseRunner extends AbstractPhpUnitTestCaseRunner { @Override protected String execute(String template_file) throws IOException, Exception { - host.saveTextFile(my_temp_dir+"/php.ini", ini.toString()); + // TODO handle INI with test-pack runner + // host.saveTextFile(my_temp_dir+"/php.ini", ini.toString()); + if (web!=null && !new File(web.getDocroot()).equals(new File(my_temp_dir))) + web = null; String resp = http_execute("/test.php"); - if (resp.contains("404")) { + /*if (resp.contains("404")) { System.out.println("404 "+web); System.exit(0); - } + }*/ - web.close(); + //web.close(); return resp; } @@ -135,7 +138,7 @@ public class HttpPhpUnitTestCaseRunner extends AbstractPhpUnitTestCaseRunner { try { if (web!=null) { synchronized(web) { - WebServerInstance _web = smgr.getWebServerInstance(cm, host, build, ini, env, my_temp_dir, web, false, test_case); + WebServerInstance _web = smgr.getWebServerInstance(cm, host, scenario_set, build, ini, env, my_temp_dir, web, false, test_case); if (_web!=this.web) { this.web = _web; is_replacement = true; @@ -154,7 +157,7 @@ public class HttpPhpUnitTestCaseRunner extends AbstractPhpUnitTestCaseRunner { if (web==null) { // test should be a FAIL or CRASH // its certainly the fault of a test (not PFTT) if not this test - this.web = smgr.getWebServerInstance(cm, host, build, ini, env, my_temp_dir, web, false, test_case); + web = smgr.getWebServerInstance(cm, host, scenario_set, build, ini, env, my_temp_dir, web, false, test_case); if (web==null||web.isCrashed()) { markTestAsCrash(); @@ -182,7 +185,6 @@ public class HttpPhpUnitTestCaseRunner extends AbstractPhpUnitTestCaseRunner { // debug them. if user doesn't, they'll click close in WER popup web.close(); } - } } } diff --git a/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java b/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java index 8fd48cf..8b7c7d2 100644 --- a/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java +++ b/src/com/mostc/pftt/runner/HttpPhptTestCaseRunner.java @@ -309,7 +309,7 @@ public class HttpPhptTestCaseRunner extends AbstractPhptTestCaseRunner2 { try { if (web!=null) { synchronized(web) { - WebServerInstance _web = smgr.getWebServerInstance(cm, host, build, ini, env, active_test_pack.getStorageDirectory(), web, false, test_case); + WebServerInstance _web = smgr.getWebServerInstance(cm, host, scenario_set, build, ini, env, active_test_pack.getStorageDirectory(), web, false, test_case); if (_web!=this.web) { this.web = _web; is_replacement = true; @@ -328,7 +328,7 @@ public class HttpPhptTestCaseRunner extends AbstractPhptTestCaseRunner2 { if (web==null) { // test should be a FAIL or CRASH // its certainly the fault of a test (not PFTT) if not this test - this.web = smgr.getWebServerInstance(cm, host, build, ini, env, active_test_pack.getStorageDirectory(), web, false, test_case); + this.web = smgr.getWebServerInstance(cm, host, scenario_set, build, ini, env, active_test_pack.getStorageDirectory(), web, false, test_case); if (web==null||web.isCrashed()) { markTestAsCrash(); diff --git a/src/com/mostc/pftt/runner/LocalPhpUnitTestPackRunner.java b/src/com/mostc/pftt/runner/LocalPhpUnitTestPackRunner.java index c8d59b2..93064d5 100644 --- a/src/com/mostc/pftt/runner/LocalPhpUnitTestPackRunner.java +++ b/src/com/mostc/pftt/runner/LocalPhpUnitTestPackRunner.java @@ -32,12 +32,7 @@ import com.mostc.pftt.results.ITestResultReceiver; import com.mostc.pftt.scenario.AbstractFileSystemScenario.ITestPackStorageDir; import com.mostc.pftt.scenario.ScenarioSet; -// TODO sapiscenario support for creating testcase runner // TODO NTS testcase support -// file: __CG__SymfonyBridgeDoctrineTestsFixturesCompositeIdentEntity.php -// dir: symfony2_finder -// database -// TODO result-pack support // TODO when RESTARTING_AND_RETRYING, should report CRASH public class LocalPhpUnitTestPackRunner extends AbstractLocalTestPackRunner<PhpUnitActiveTestPack, PhpUnitSourceTestPack, PhpUnitTestCase> { final Map<String,String> globals = new HashMap<String,String>(); @@ -88,21 +83,22 @@ public class LocalPhpUnitTestPackRunner extends AbstractLocalTestPackRunner<PhpU } @Override - protected PhpUnitThread createTestPackThread(boolean parallel) { + protected PhpUnitThread createTestPackThread(boolean parallel) throws IllegalStateException, IOException { return new PhpUnitThread(parallel); } public class PhpUnitThread extends TestPackThread<PhpUnitTestCase> { final String my_temp_dir; - protected PhpUnitThread(boolean parallel) { + protected PhpUnitThread(boolean parallel) throws IllegalStateException, IOException { super(parallel); my_temp_dir = runner_host.fixPath(runner_host.mktempname(runner_host.getPhpSdkDir()+"/temp/", getClass()) + "/"); + runner_host.mkdirs(my_temp_dir); } @Override protected void runTest(TestCaseGroupKey group_key, PhpUnitTestCase test_case) throws IOException, Exception, Throwable { - AbstractPhpUnitTestCaseRunner r = sapi_scenario.createPhpUnitTestCaseRunner(cm, twriter, globals, env, runner_host, scenario_set, build, test_case, my_temp_dir, constants, test_case.php_unit_dist.getIncludePath(), test_case.php_unit_dist.getIncludeFiles()); + AbstractPhpUnitTestCaseRunner r = sapi_scenario.createPhpUnitTestCaseRunner(this, group_key, cm, twriter, globals, env, runner_host, scenario_set, build, test_case, my_temp_dir, constants, test_case.php_unit_dist.getIncludePath(), test_case.php_unit_dist.getIncludeFiles()); r.runTest(); } diff --git a/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java b/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java index b6e040a..30e0b20 100644 --- a/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java +++ b/src/com/mostc/pftt/scenario/AbstractSAPIScenario.java @@ -15,6 +15,7 @@ import com.mostc.pftt.results.ConsoleManager; import com.mostc.pftt.results.ITestResultReceiver; import com.mostc.pftt.runner.AbstractPhpUnitTestCaseRunner; import com.mostc.pftt.runner.AbstractPhptTestCaseRunner; +import com.mostc.pftt.runner.LocalPhpUnitTestPackRunner.PhpUnitThread; import com.mostc.pftt.runner.LocalPhptTestPackRunner.PhptThread; /** Different scenarios for how PHP can be run @@ -91,6 +92,6 @@ public abstract class AbstractSAPIScenario extends AbstractSerialScenario { public abstract PhpIni createIniForTest(ConsoleManager cm, AHost host, PhpBuild build, PhptActiveTestPack active_test_pack, ScenarioSet scenario_set); - public abstract AbstractPhpUnitTestCaseRunner createPhpUnitTestCaseRunner(ConsoleManager cm, ITestResultReceiver twriter, Map<String,String> globals, Map<String,String> env, AHost runner_host, ScenarioSet scenario_set, PhpBuild build, PhpUnitTestCase test_case, String my_temp_dir, Map<String,String> constants, String include_path, String[] include_files); + public abstract AbstractPhpUnitTestCaseRunner createPhpUnitTestCaseRunner(PhpUnitThread thread, TestCaseGroupKey group_key, ConsoleManager cm, ITestResultReceiver twriter, Map<String,String> globals, Map<String,String> env, AHost runner_host, ScenarioSet scenario_set, PhpBuild build, PhpUnitTestCase test_case, String my_temp_dir, Map<String,String> constants, String include_path, String[] include_files); } // end public abstract class AbstractSAPIScenario diff --git a/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java b/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java index ca2f51e..444c81f 100644 --- a/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java +++ b/src/com/mostc/pftt/scenario/AbstractWebServerScenario.java @@ -38,6 +38,7 @@ import com.mostc.pftt.runner.AbstractPhpUnitTestCaseRunner; import com.mostc.pftt.runner.AbstractPhptTestCaseRunner; import com.mostc.pftt.runner.HttpPhpUnitTestCaseRunner; import com.mostc.pftt.runner.HttpPhptTestCaseRunner; +import com.mostc.pftt.runner.LocalPhpUnitTestPackRunner.PhpUnitThread; import com.mostc.pftt.runner.LocalPhptTestPackRunner.PhptThread; /** scenarios for testing PHP while its running under a web server @@ -97,7 +98,7 @@ public abstract class AbstractWebServerScenario extends AbstractSAPIScenario { */ public EScenarioStartState start(ConsoleManager cm, Host host, PhpBuild build, ScenarioSet scenario_set, final String docroot) { if (host instanceof AHost) { - return smgr.getWebServerInstance(cm, (AHost)host, build, null, null, docroot, null, false, this).isRunning() ? EScenarioStartState.STARTED : EScenarioStartState.FAILED_TO_START; + return smgr.getWebServerInstance(cm, (AHost)host, scenario_set, build, null, null, docroot, null, false, this).isRunning() ? EScenarioStartState.STARTED : EScenarioStartState.FAILED_TO_START; } else { EScenarioStartState state = EScenarioStartState.SKIP, _state = null; for (Host h : (HostGroup)host ) { @@ -172,8 +173,9 @@ public abstract class AbstractWebServerScenario extends AbstractSAPIScenario { return HttpPhptTestCaseRunner.willSkip(cm, twriter, host, scenario_set, type, build, test_case); } - public AbstractPhpUnitTestCaseRunner createPhpUnitTestCaseRunner(ConsoleManager cm, ITestResultReceiver twriter, Map<String,String> globals, Map<String,String> env, AHost runner_host, ScenarioSet scenario_set, PhpBuild build, PhpUnitTestCase test_case, String my_temp_dir, Map<String,String> constants, String include_path, String[] include_files) { - return new HttpPhpUnitTestCaseRunner(twriter, params, httpproc, httpexecutor, smgr, null, globals, env, cm, runner_host, scenario_set, build, test_case, my_temp_dir, constants, include_path, include_files); + @Override + public AbstractPhpUnitTestCaseRunner createPhpUnitTestCaseRunner(PhpUnitThread thread, TestCaseGroupKey group_key, ConsoleManager cm, ITestResultReceiver twriter, Map<String,String> globals, Map<String,String> env, AHost runner_host, ScenarioSet scenario_set, PhpBuild build, PhpUnitTestCase test_case, String my_temp_dir, Map<String,String> constants, String include_path, String[] include_files) { + return new HttpPhpUnitTestCaseRunner(twriter, params, httpproc, httpexecutor, smgr, (WebServerInstance) ((SharedSAPIInstanceTestCaseGroupKey)group_key).getSAPIInstance(), globals, env, cm, runner_host, scenario_set, build, test_case, my_temp_dir, constants, include_path, include_files); } } // end public abstract class AbstractWebServerScenario diff --git a/src/com/mostc/pftt/scenario/CLIScenario.java b/src/com/mostc/pftt/scenario/CLIScenario.java index c9926c9..3b81735 100644 --- a/src/com/mostc/pftt/scenario/CLIScenario.java +++ b/src/com/mostc/pftt/scenario/CLIScenario.java @@ -18,7 +18,7 @@ import com.mostc.pftt.runner.AbstractPhpUnitTestCaseRunner; import com.mostc.pftt.runner.AbstractPhptTestCaseRunner; import com.mostc.pftt.runner.CliPhpUnitTestCaseRunner; import com.mostc.pftt.runner.CliPhptTestCaseRunner; -import com.mostc.pftt.runner.HttpPhpUnitTestCaseRunner; +import com.mostc.pftt.runner.LocalPhpUnitTestPackRunner.PhpUnitThread; import com.mostc.pftt.runner.LocalPhptTestPackRunner.PhptThread; /** Tests the Command Line Interface(CLI) for running PHP. @@ -92,7 +92,7 @@ public class CliScenario extends AbstractSAPIScenario { } @Override - public AbstractPhpUnitTestCaseRunner createPhpUnitTestCaseRunner(ConsoleManager cm, ITestResultReceiver twriter, Map<String, String> globals, Map<String, String> env, AHost runner_host, ScenarioSet scenario_set, PhpBuild build, PhpUnitTestCase test_case, String my_temp_dir, Map<String, String> constants, String include_path, String[] include_files) { + public AbstractPhpUnitTestCaseRunner createPhpUnitTestCaseRunner(PhpUnitThread thread, TestCaseGroupKey group_key, ConsoleManager cm, ITestResultReceiver twriter, Map<String, String> globals, Map<String, String> env, AHost runner_host, ScenarioSet scenario_set, PhpBuild build, PhpUnitTestCase test_case, String my_temp_dir, Map<String, String> constants, String include_path, String[] include_files) { return new CliPhpUnitTestCaseRunner(twriter, globals, env, cm, runner_host, scenario_set, build, test_case, my_temp_dir, constants, test_case.php_unit_dist.getIncludePath(), test_case.php_unit_dist.getIncludeFiles()); }