Commit: 57572767543b8d116466755f855ec09f611b25df Author: Matt Ficken <v-maf...@microsoft.com> Thu, 12 Sep 2013 15:19:30 -0700 Parents: fa95ddb2e16f3cebacdd80e81f273bda7d06d375 Branches: master
Link: http://git.php.net/?p=pftt2.git;a=commitdiff;h=57572767543b8d116466755f855ec09f611b25df Log: config files in phpt test-packs Former-commit-id: 2a0a1072e3a13e660c452b6b69d53a2b744ff8f0 Changed paths: M src/com/mostc/pftt/host/PSCAgentServer.java M src/com/mostc/pftt/host/RemotePhptTestPackRunner.java M src/com/mostc/pftt/main/Config.java M src/com/mostc/pftt/main/PfttMain.java M src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java M src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java M src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java M src/com/mostc/pftt/runner/AbstractTestPackRunner.java
diff --git a/src/com/mostc/pftt/host/PSCAgentServer.java b/src/com/mostc/pftt/host/PSCAgentServer.java index 4e39122..38a432a 100644 --- a/src/com/mostc/pftt/host/PSCAgentServer.java +++ b/src/com/mostc/pftt/host/PSCAgentServer.java @@ -180,6 +180,11 @@ public abstract class PSCAgentServer implements ConsoleManager, ITestResultRecei } @Override + public long getMaxRunTimeMillis() { + return 0; + } + + @Override public void notifyStart(AHost this_host, ScenarioSetSetup this_scenario_set, PhptSourceTestPack src_test_pack, PhptTestCase test_case) { // TODO Auto-generated method stub } diff --git a/src/com/mostc/pftt/host/RemotePhptTestPackRunner.java b/src/com/mostc/pftt/host/RemotePhptTestPackRunner.java index 4796523..f5d699e 100644 --- a/src/com/mostc/pftt/host/RemotePhptTestPackRunner.java +++ b/src/com/mostc/pftt/host/RemotePhptTestPackRunner.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.io.PrintStream; import com.github.mattficken.io.StringUtil; +import com.mostc.pftt.main.Config; import com.mostc.pftt.model.core.PhpBuild; import com.mostc.pftt.model.core.PhptActiveTestPack; import com.mostc.pftt.model.core.PhptSourceTestPack; @@ -53,13 +54,14 @@ public class RemotePhptTestPackRunner extends AbstractRemoteTestPackRunner<PhptA public static void main(String[] args) throws Exception { LocalHost host = new LocalHost(); - LocalConsoleManager cm = new LocalConsoleManager(null, null, false, false, false, false, true, false, true, false, false, false, 1, 1, true, 1, 1, 1, null, null, null, null, false, 0, 0, false, false, 0, 0, 0, false); + LocalConsoleManager cm = new LocalConsoleManager(null, null, false, false, false, false, true, false, true, false, false, false, 1, 1, true, 1, 1, 1, null, null, null, null, false, 0, 0, false, false, 0, 0, 0, false, 0); + Config config = Config.loadConfigFromFiles(cm, "default"); PhpBuild build = new PhpBuild("C:\\php-sdk\\php-5.5-ts-windows-vc11-x64-re3aeb6c"); build.open(cm, host); PhptSourceTestPack test_pack = new PhptSourceTestPack("C:\\php-sdk\\php-test-pack-5.5-ts-windows-vc11-x86-r0704e4b"); - test_pack.open(cm, host); + test_pack.open(cm, config, host); PhpResultPackWriter tmgr = new PhpResultPackWriter(host, cm, new File(host.getPhpSdkDir()), build, test_pack, null); diff --git a/src/com/mostc/pftt/main/Config.java b/src/com/mostc/pftt/main/Config.java index 1cd19f6..ddb3814 100644 --- a/src/com/mostc/pftt/main/Config.java +++ b/src/com/mostc/pftt/main/Config.java @@ -38,9 +38,11 @@ import com.mostc.pftt.results.ITestResultReceiver; import com.mostc.pftt.results.PhpResultPackWriter; import com.mostc.pftt.results.PhpUnitTestResult; import com.mostc.pftt.results.PhptTestResult; +import com.mostc.pftt.runner.AbstractLocalTestPackRunner.TestPackThread; import com.mostc.pftt.scenario.EScenarioSetPermutationLayer; import com.mostc.pftt.scenario.Scenario; import com.mostc.pftt.scenario.ScenarioSet; +import com.mostc.pftt.scenario.ScenarioSetSetup; import com.mostc.pftt.scenario.app.JoomlaScenario; import groovy.lang.GroovyClassLoader; @@ -133,6 +135,8 @@ public final class Config implements IENVINIFilter { public static final String PROCESS_PHPUNIT_TEST_PACK_METHOD_NAME = "processPhpUnitTestPack"; public static final String PROCESS_PHPT_TEST_RESULT_METHOD_NAME = "processPhptTestResult"; public static final String PROCESS_PHP_UNIT_TEST_RESULT_METHOD_NAME = "processPhpUnitTestResult"; + public static final String PREPARE_TEST_PACK_PER_THREAD_METHOD_NAME = "prepareTestPackPerThread"; + public static final String PREPARE_TEST_PACK_METHOD_NAME = "prepareTestPack"; // protected final LinkedList<AHost> hosts; protected final LinkedList<Scenario> scenarios; @@ -170,6 +174,26 @@ public final class Config implements IENVINIFilter { // ex: internal_examples - copy to internal } + public void prepareTestPack(ConsoleManager cm, AHost host, ScenarioSetSetup setup, PhpBuild build, PhptSourceTestPack test_pack) { + ArrayList<MethodImpl> methods = by_method_name.get(PREPARE_TEST_PACK_METHOD_NAME); + if (methods==null||methods.isEmpty()) + return; + cm.println(EPrintType.IN_PROGRESS, getClass(), "preparing test pack from configuration... "+setup+" "+test_pack); + for ( MethodImpl m : methods ) { + invokeMethod(null, null, m.go, PREPARE_TEST_PACK_METHOD_NAME, new Object[]{cm, host, setup, build, test_pack}, null); + } + } + + public void prepareTestPackPerThread(ConsoleManager cm, AHost host, TestPackThread test_pack_thread, ScenarioSetSetup setup, PhpBuild build, PhptSourceTestPack test_pack) { + ArrayList<MethodImpl> methods = by_method_name.get(PREPARE_TEST_PACK_PER_THREAD_METHOD_NAME); + if (methods==null||methods.isEmpty()) + return; + cm.println(EPrintType.IN_PROGRESS, getClass(), "preparing test pack per thread from configuration... "+test_pack_thread+" "+setup+" "+test_pack); + for ( MethodImpl m : methods ) { + invokeMethod(null, null, m.go, PREPARE_TEST_PACK_PER_THREAD_METHOD_NAME, new Object[]{cm, host, test_pack_thread, setup, build, test_pack}, null); + } + } + public void processPHPTTestPack(PhptSourceTestPack test_pack, PhpResultPackWriter twriter, PhpBuild build) { ArrayList<MethodImpl> methods = by_method_name.get(PROCESS_PHPT_TEST_PACK_METHOD_NAME); if (methods==null) @@ -279,7 +303,7 @@ public final class Config implements IENVINIFilter { while (it.hasNext()) { nv = it.next().getName().toLowerCase(); for ( String str : not_scenarios ) { - if (nv.contains(str.toLowerCase())) { + if (nv.equalsIgnoreCase(str)) { // match, remove it it.remove(); break; @@ -321,10 +345,16 @@ public final class Config implements IENVINIFilter { this_scenario_sets = not(getNotScenarios(cm), permuteScenarioSets(cm, layer)); + HashMap<String,ScenarioSet> map = new HashMap<String,ScenarioSet>(); + for ( ScenarioSet s : this_scenario_sets ) + map.put(s.toString(), s); + ArrayList<ScenarioSet> a = new ArrayList<ScenarioSet>(map.size()); + a.addAll(map.values()); + // cache for next time (this config won't change, so its ok to cache) - permuted_scenario_sets.put(layer, this_scenario_sets); + permuted_scenario_sets.put(layer, a); - return this_scenario_sets; + return a; } public List<ScenarioSet> getScenarioSets(EScenarioSetPermutationLayer layer) { @@ -568,6 +598,12 @@ public final class Config implements IENVINIFilter { * @throws IOException */ public static Config loadConfigFromFiles(ConsoleManager cm, File... files) throws CompilationFailedException, InstantiationException, IllegalAccessException, IOException { + Config config = new Config(); + config.doLoadConfigFromFiles(cm, files); + return config; + } + + protected void doLoadConfigFromFiles(ConsoleManager cm, File... files) throws InstantiationException, IllegalAccessException, CompilationFailedException, FileNotFoundException, IOException { GroovyClassLoader loader = new GroovyClassLoader(Config.class.getClassLoader()); /*ImportCustomizer ic = new ImportCustomizer(); @@ -577,8 +613,6 @@ public final class Config implements IENVINIFilter { cc.addCompilationCustomizers(ic); */ - Config config = new Config(); - // don't load default scenarios. configuration file(s) completely replace them (not merged) LinkedList<Scenario> scenarios = new LinkedList<Scenario>(); @@ -591,11 +625,11 @@ public final class Config implements IENVINIFilter { go = (GroovyObject) clazz.newInstance(); // call methods in file to get configuration (hosts, etc...) - loadObjectToConfig(cm, config, go, scenarios, file.getAbsolutePath()); + loadObjectToConfig(cm, this, go, scenarios, file.getAbsolutePath()); } - return loadConfigCommon(cm, scenarios, config); - } // end public static Config loadConfigFromFiles + loadConfigCommon(cm, scenarios, this); + } protected static String importString(String filename, String code) { // a hack to import common classes for configuration files (XXX do this a better way) @@ -744,6 +778,8 @@ public final class Config implements IENVINIFilter { registerMethod(cm, config, go, PROCESS_PHPUNIT_TEST_PACK_METHOD_NAME, file_name); registerMethod(cm, config, go, PROCESS_PHPT_TEST_RESULT_METHOD_NAME, file_name); registerMethod(cm, config, go, PROCESS_PHP_UNIT_TEST_RESULT_METHOD_NAME, file_name); + registerMethod(cm, config, go, PREPARE_TEST_PACK_PER_THREAD_METHOD_NAME, file_name); + registerMethod(cm, config, go, PREPARE_TEST_PACK_METHOD_NAME, file_name); } // end protected static void loadObjectToConfig private static void checkImplemented(ConsoleManager cm, Scenario o) { @@ -808,5 +844,9 @@ public final class Config implements IENVINIFilter { } return false; } + + public void addConfigFile(ConsoleManager cm, File file) throws CompilationFailedException, FileNotFoundException, InstantiationException, IllegalAccessException, IOException { + doLoadConfigFromFiles(cm, file); + } } // end public final class ConfigUtil diff --git a/src/com/mostc/pftt/main/PfttMain.java b/src/com/mostc/pftt/main/PfttMain.java index 64ea5c0..f99357d 100644 --- a/src/com/mostc/pftt/main/PfttMain.java +++ b/src/com/mostc/pftt/main/PfttMain.java @@ -85,11 +85,7 @@ import com.mostc.pftt.util.WindowsSnapshotDownloadUtil.FindBuildTestPackPair; // -test the php build // -test the web server build // -/* -rename ostcpftt@ name to `OSTC PFTT Unattended Test System` - -name still clear who owns it - -plus database field would tell - -only `php` is missing from new name, but any 2nd/3rd party who saw the name wouldn't care about that - -just care about owner*/ +// no component should be allowed to run forever(implicitly it will eventually break), always have explicit timeouts // TODO enchant scenario // skips on 5.4 cli apache ts @@ -113,7 +109,6 @@ import com.mostc.pftt.util.WindowsSnapshotDownloadUtil.FindBuildTestPackPair; // -or include in pftt's cache/dep // -use mssql PHPTs as a separate PhptTestPack until they are integrated with PhpCore // TODO xdebug only for 5.4-ts -// TODO task/code_coverage store in result-pack // TODO get code coverage data of Symfony demo app (UI?) // -get list of builtin functions // -find phpunit tests that use same builtin functions @@ -156,14 +151,6 @@ import com.mostc.pftt.util.WindowsSnapshotDownloadUtil.FindBuildTestPackPair; // aa -c dev/symfony-2.3 // dev/ indicates conf/dev for config file // TODO include Selenium WebDriver in javadoc -// TODO WincacheUScenario -// -and APCUScenario -// which both extend UserCache (not a code cache) - can use with and without opcache or apc or wincache -// -// > mediawiki can use WinCacheU for its user/object cache -// -makes a major performance difference -// -make it a point to unit test that! -// // TODO progress indicator for `release_get` // TODO soap xmlrpc ftp snmp ldap postgresql curl ftp - including symfony, joomla, phpt // pdo_odbc odbc (to mssql??) @@ -594,6 +581,31 @@ public class PfttMain { cm.println(EPrintType.CLUE, PfttMain.class, "Writing Result-Pack: "+tmgr.getResultPackPath()); for (ScenarioSet scenario_set : getScenarioSets(config, EScenarioSetPermutationLayer.FUNCTIONAL_TEST_APPLICATION)) { + if (!cm.isSkipSmokeTests()) { + { + // TODO test running PHPTs on a build that is missing a DLL that is + RequiredExtensionsSmokeTest test = new RequiredExtensionsSmokeTest(); + // + // on Windows, missing .DLLs from a php build will cause a blocking winpop dialog msg to appear + // in such a case, the test will timeout after 1 minute and then fail (stopping at that point is important) + // @see PhpBuild#getExtensionList + if (test.test(build, cm, host, SAPIScenario.getSAPIScenario(scenario_set).getSAPIType(), tmgr)==ESmokeTestStatus.FAIL) { + // if this test fails, RequiredFeaturesSmokeTest will fail for sure + cm.println(EPrintType.CANT_CONTINUE, "Main", "Failed smoke test: "+test.getName()); + + break; + } + } + { + RequiredFeaturesSmokeTest test = new RequiredFeaturesSmokeTest(); + if (test.test(build, cm, host, tmgr)==ESmokeTestStatus.FAIL) { + cm.println(EPrintType.CANT_CONTINUE, "Main", "Failed smoke test: "+test.getName()); + + break; + } + } + } + List<AHost> hosts = config.getHosts(); AHost host = hosts.isEmpty()?this.host:hosts.get(0); LocalPhpUnitTestPackRunner r = new LocalPhpUnitTestPackRunner(cm, tmgr, scenario_set, build, host, host); @@ -1143,12 +1155,12 @@ public class PfttMain { return (PhpBuild[]) builds.toArray(new PhpBuild[builds.size()]); } // end protected static PhpBuild[] newBuilds - protected static PhptSourceTestPack newTestPack(ConsoleManager cm, AHost host, String path) { + protected static PhptSourceTestPack newTestPack(ConsoleManager cm, Config config, AHost host, String path) { PhptSourceTestPack test_pack = new PhptSourceTestPack(path); - if (test_pack.open(cm, host)) + if (test_pack.open(cm, config, host)) return test_pack; test_pack = new PhptSourceTestPack(host.getPhpSdkDir() + "/" + path); - if (test_pack.open(cm, host)) + if (test_pack.open(cm, config, host)) return test_pack; else return null; // test-pack not found/readable error @@ -1296,7 +1308,7 @@ public class PfttMain { System.exit(-255); System.out.println("PFTT: Config: loaded "+config_files); } else { - File default_config_file = new File(new LocalHost().getPfttDir()+"/conf/default.groovy"); + File default_config_file = new File(new LocalHost().getPfttConfDir()+"/default.groovy"); config = Config.loadConfigFromFiles(cm, default_config_file); System.out.println("PFTT: Config: no config files loaded... using default only ("+default_config_file+")"); } @@ -1582,7 +1594,7 @@ public class PfttMain { PhpBuild[] builds = newBuilds(cm, p.host, args[args_i+1]); - PhptSourceTestPack test_pack = newTestPack(cm, p.host, args[args_i+2]); + PhptSourceTestPack test_pack = newTestPack(cm, config, p.host, args[args_i+2]); if (test_pack==null) { System.err.println("IO Error: can not open php test pack: "+test_pack); System.exit(-255); @@ -1613,7 +1625,7 @@ public class PfttMain { PhpBuild[] builds = newBuilds(cm, p.host, args[args_i+1]); - PhptSourceTestPack test_pack = newTestPack(cm, p.host, args[args_i+2]); + PhptSourceTestPack test_pack = newTestPack(cm, config, p.host, args[args_i+2]); if (test_pack == null) { System.err.println("IO Error: can not open php test pack: "+test_pack); System.exit(-255); @@ -1644,7 +1656,7 @@ public class PfttMain { PhpBuild[] builds = newBuilds(cm, p.host, args[args_i+1]); - PhptSourceTestPack test_pack = newTestPack(cm, p.host, args[args_i+2]); + PhptSourceTestPack test_pack = newTestPack(cm, config, p.host, args[args_i+2]); if (test_pack == null) { System.err.println("IO Error: can not open php test pack: "+test_pack); System.exit(-255); @@ -1667,7 +1679,7 @@ public class PfttMain { PhpBuild[] builds = newBuilds(cm, p.host, args[args_i+1]); - PhptSourceTestPack test_pack = newTestPack(cm, p.host, args[args_i+2]); + PhptSourceTestPack test_pack = newTestPack(cm, config, p.host, args[args_i+2]); if (test_pack==null) { System.err.println("IO Error: can not open php test pack: "+test_pack); System.exit(-255); @@ -1759,7 +1771,7 @@ public class PfttMain { } else if (command.equals("setup")||command.equals("set")||command.equals("setu")) { if (!(args.length > args_i+1)) { System.err.println("User Error: must include build"); - System.out.println("usage: pftt [-c config_files ]setup <path to PHP build>"); + System.out.println("usage: pftt [-c config_files ]setup <path to PHP build> [optional: PHPT test-pack to setup]"); System.exit(-255); return; } @@ -1770,13 +1782,21 @@ public class PfttMain { // setup all scenarios PhpIni ini; + ScenarioSetSetup setup = null; for ( ScenarioSet set : getScenarioSets(config, EScenarioSetPermutationLayer.PRODUCTION_OR_ALL_UP_TEST) ) { ini = RequiredExtensionsSmokeTest.createDefaultIniCopy(cm, p.host, build); INIScenario.setupScenarios(cm, p.host, set, build, ini); - ScenarioSetSetup.setupScenarioSet(cm, p.host, build, set, EScenarioSetPermutationLayer.PRODUCTION_OR_ALL_UP_TEST); + setup = ScenarioSetSetup.setupScenarioSet(cm, p.host, build, set, EScenarioSetPermutationLayer.PRODUCTION_OR_ALL_UP_TEST); + + } + if (setup != null && args.length > args_i+2) { + // this will load the test-pack's configuration script (if present) + PhptSourceTestPack test_pack = PfttMain.newTestPack(cm, config, p.host, args[args_i+2]); + // use last ScenarioSetSetup + config.prepareTestPack(cm, p.host, setup, build, test_pack); } } else if (command.equals("release_get")||command.equals("rgn")||command.equals("rgnew")||command.equals("rgnewest")||command.equals("rgp")||command.equals("rgprev")||command.equals("rgprevious")||command.equals("rg")||command.equals("rget")) { EBuildBranch branch = null; diff --git a/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java b/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java index d0a374a..bbe4a3d 100644 --- a/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java +++ b/src/com/mostc/pftt/runner/AbstractLocalTestPackRunner.java @@ -8,6 +8,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Random; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -38,8 +39,10 @@ import com.mostc.pftt.results.PhpResultPackWriter; import com.mostc.pftt.runner.LocalPhpUnitTestPackRunner.PhpUnitThread; import com.mostc.pftt.scenario.EScenarioSetPermutationLayer; import com.mostc.pftt.scenario.FileSystemScenario; +import com.mostc.pftt.scenario.IScenarioSetup; import com.mostc.pftt.scenario.RemoteFileSystemScenario; import com.mostc.pftt.scenario.SAPIScenario; +import com.mostc.pftt.scenario.Scenario; import com.mostc.pftt.scenario.WebServerScenario; import com.mostc.pftt.scenario.ScenarioSet; import com.mostc.pftt.scenario.FileSystemScenario.ITestPackStorageDir; @@ -54,10 +57,11 @@ import com.mostc.pftt.util.ErrorUtil; */ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S extends SourceTestPack<A,T>, T extends TestCase> extends AbstractTestPackRunner<S, T> { - protected static final int MAX_THREAD_COUNT = 128; + protected static final int MAX_USER_SPECIFIED_THREAD_COUNT = 192; protected S src_test_pack; protected final ConsoleManager cm; protected final ITestResultReceiver twriter; + protected long start_time_millis; protected int thread_safe_test_count; protected A active_test_pack; protected AtomicReference<ETestPackRunnerState> runner_state; @@ -176,7 +180,7 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex return null; } // - cm.println(EPrintType.CLUE, getClass(), "Scenario Set: "+scenario_set.getName()); + cm.println(EPrintType.CLUE, getClass(), "Scenario Set: "+scenario_set_setup.getNameWithVersionInfo()); setupStorageAndTestPack(storage_dir, test_cases); return storage_dir; @@ -259,11 +263,11 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex cm.println(EPrintType.IN_PROGRESS, getClass(), "ready to go! scenario_set="+scenario_set+" runner_host="+runner_host+" storage_dir="+storage_dir.getClass()+" local_path="+storage_dir.getLocalPath(runner_host)+" remote_path="+storage_dir.getRemotePath(runner_host)); - long start_time = System.currentTimeMillis(); + start_time_millis = System.currentTimeMillis(); executeTestCases(true); // TODO false); - long run_time = Math.abs(System.currentTimeMillis() - start_time); + final long run_time = Math.abs(System.currentTimeMillis() - start_time_millis); cm.println(EPrintType.CLUE, getClass(), "Finished test run in "+(run_time/1000)+" seconds"); @@ -281,6 +285,7 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex // showTally(); + cm.println(EPrintType.CLUE, getClass(), "Scenario Set: "+scenario_set); } finally { // be sure all running WebServerInstances, or other SAPIInstances are // closed by end of testing (otherwise `php.exe -S` will keep on running) @@ -481,46 +486,63 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex } - protected int decideThreadCount() { - // 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. if debugging - // 4. ask user (-thread_count console option) - // 5. limit to MAX_THREAD_COUNT - - int thread_count = sapi_scenario.getTestThreadCount(runner_host); - if ((cm.isThreadSafety() || cm.getRunTestTimesAll()<2) && thread_count > thread_safe_test_count + non_thread_safe_exts.size()) { + protected int init_thread_count, max_thread_count; + protected void decideThreadCount() { + init_thread_count = runner_host.getCPUCount(); + if ((cm.isThreadSafety() || cm.getRunTestTimesAll()<2) && init_thread_count > thread_safe_groups.size() + non_thread_safe_exts.size()) { // don't start more threads than there will be work for // however, if -no_nts AND -run_test_times_all console option used, user wants tests run // as much as possible, so don't do this check (in that case, do normal number of threads, not this) // - thread_count = thread_safe_test_count + non_thread_safe_exts.size(); + init_thread_count = thread_safe_test_count + non_thread_safe_exts.size(); + } + max_thread_count = init_thread_count * 2; + // ask scenarios for approval (primarily SAPIScenario and WinCacheUScenario) + { + // ask sapi scenario first + init_thread_count = sapi_scenario.getApprovedInitialThreadPoolSize(runner_host, init_thread_count); + max_thread_count = sapi_scenario.getApprovedMaximumThreadPoolSize(runner_host, max_thread_count); + // ask all other scenarios + for ( Scenario s : scenario_set ) { + if (s==sapi_scenario) + continue; + int a = s.getApprovedInitialThreadPoolSize(runner_host, init_thread_count); + int b = s.getApprovedMaximumThreadPoolSize(runner_host, max_thread_count); + if (a<init_thread_count) + init_thread_count = a; + if (b<max_thread_count) + max_thread_count = b; + } } 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 really SLoow) - thread_count = Math.max(1, thread_count / 4); + init_thread_count = Math.max(1, init_thread_count / 4); } if (cm.getThreadCount()>0) { // let user override SAPI and debug thread count checks - thread_count = cm.getThreadCount(); - } - if (thread_count > MAX_THREAD_COUNT) { - // safety check: don't run too many threads - thread_count = MAX_THREAD_COUNT; - } - return thread_count; - } // end protected int decideThreadCount + init_thread_count = cm.getThreadCount(); + } + + checkThreadCountLimit(); + } // end protected void decideThreadCount + + protected void checkThreadCountLimit() { + if (init_thread_count>max_thread_count) + max_thread_count = init_thread_count; + if (init_thread_count>MAX_USER_SPECIFIED_THREAD_COUNT) + init_thread_count = MAX_USER_SPECIFIED_THREAD_COUNT; + if (max_thread_count>MAX_USER_SPECIFIED_THREAD_COUNT) + max_thread_count = MAX_USER_SPECIFIED_THREAD_COUNT; + } protected void executeTestCases(boolean parallel) throws InterruptedException, IllegalStateException, IOException { - int thread_count = decideThreadCount(); - cm.println(EPrintType.IN_PROGRESS, getClass(), "Starting up Test Threads: thread_count="+thread_count+" runner_host="+runner_host+" sapi_scenario="+sapi_scenario); + decideThreadCount(); + cm.println(EPrintType.IN_PROGRESS, getClass(), "Starting up Test Threads: thread_count="+init_thread_count+" max="+max_thread_count+" runner_host="+runner_host+" sapi_scenario="+sapi_scenario); test_count.set(0); - for ( int i=0 ; i < thread_count ; i++ ) { + for ( int i=0 ; i < init_thread_count ; i++ ) { start_thread(parallel); } @@ -544,7 +566,7 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex // run a timer task while the test is running to kill the test if it takes too long // // wait a while before killing it (double the max runtime for the test) - if ((test_run_start_time>0&&Math.abs(System.currentTimeMillis()-test_run_start_time)>120000)) { + if (!thread.shouldRun()||(test_run_start_time>0&&Math.abs(System.currentTimeMillis()-test_run_start_time)>120000)) { // thread running too long if (thread.isDebuggerAttached()) { not_running = false; // keep running @@ -639,7 +661,7 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex // (if there aren't enough NTS extensions to fill all the threads, some threads will only execute thread-safe tests) // try { - while (shouldRun()&&!thread_safe_groups.isEmpty()) { + while (shouldRun()&&(!thread_safe_groups.isEmpty()||!non_thread_safe_exts.isEmpty())) {//thread_safe_test_count==0)) { try { runNonThreadSafe(); @@ -737,23 +759,28 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex return this; } + protected long getMaxRunTimeMillis() { + return cm.getMaxRunTimeMillis(); + } + protected boolean shouldRun() { - return run_thread.get() && runner_state.get()==ETestPackRunnerState.RUNNING; + final long max_run_time_millis = getMaxRunTimeMillis(); + return run_thread.get() && runner_state.get()==ETestPackRunnerState.RUNNING && (max_run_time_millis<1000||Math.abs(System.currentTimeMillis() - start_time_millis) < max_run_time_millis); } + protected abstract void prepareExec(TestCaseGroupKey group_key, PhpIni ini, Map<String,String> env, IScenarioSetup s); + protected void exec_jobs(TestCaseGroupKey group_key, LinkedBlockingQueue<T> jobs) { this.group_key = group_key; LinkedList<T> completed_tests = new LinkedList<T>(); this.jobs = jobs; + + for ( IScenarioSetup s :scenario_set_setup.getSetups() ) { + prepareExec(group_key, group_key.getPhpIni(), group_key.getEnv(), s); + } + while (shouldRun()) { - /*if (test_count.get() > 100 ) {//cm.getRunCount() > 0 && test_count.get() > cm.getRunCount() ) { - // run maximum number of tests, don't run any more - System.exit(0); - runner_state.set(ETestPackRunnerState.NOT_RUNNING); - break; - }*/ - // test_case = null; try { @@ -801,28 +828,6 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex thread_wsi = null; } - String name = test_case.getName(); - if (name.equals("ext/filter/tests/004.phpt") - || name.equals("ext/standard/tests/strings/htmlentities05.phpt") - || name.equals("ext/wddx/tests/004.phpt") - || name.equals("ext/wddx/tests/005.phpt") - || name.equals("ext/standard/tests/strings/htmlentities12.phpt") - || name.equals("ext/mbstring/tests/mb_ereg_replace_variation1.phpt") - || name.equals("ext/mbstring/tests/mb_ereg_replace_variation1.phpt") - || name.equals("ext/phar/tests/phar_dotted_path.phpt") - || name.equals("ext/session/tests/027.phpt") - || name.equals("tests/basic/0") - || name.startsWith("ext/mbstring/tests/mb_output") - || name.equals("ext/mbstring/tests/mb_ereg_replace_variation1.phpt") - || name.equals("ext/phar/tests/cache_list/frontcontroller13.phpt") - || name.equals("ext/phar/tests/frontcontroller29.phpt") - || name.equals("zend/tests/multibyte/multibyte_encoding_001.phpt") - || name.equals("ext/session/tests/009.phpt")) { - if(thread_wsi!=null) - thread_wsi.close(cm); - thread_wsi = null; - } - if (thread_wsi==null || ( !cm.isNoRestartAll() @@ -862,21 +867,27 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex // finally: create the test case runner and run the actual test runTest(group_key, test_case); - - if (Math.abs(System.currentTimeMillis() - test_run_start_time.get()) < sapi_scenario.getFastTestTimeSeconds()) { - // scale back down + // if test took too long OR tests are running fast now + // TODO temp test decreasing threads when getting lots of timeouts + if (Math.abs(System.currentTimeMillis() - test_run_start_time.get()) > 60 + || + Math.abs(System.currentTimeMillis() - test_run_start_time.get()) < sapi_scenario.getFastTestTimeSeconds()) { + // scale back down (decrease number of threads) Iterator<TestPackThread<T>> it = scale_up_threads.iterator(); TestPackThread<T> slow; while (it.hasNext()) { slow = it.next(); + it.remove(); if (slow.ext==null) { // stop after current test case finished - slow.run_thread.set(false); + slow.run_thread.set(false); + // remove 1 NTS thread at a time + // (each NTS thread can remove 1 at a time, so several can get removed at same time) + break; } else { // don't stop this one because ext has been dequeued // and would have gotten lost } - it.remove(); } } @@ -917,8 +928,8 @@ public abstract class AbstractLocalTestPackRunner<A extends ActiveTestPack, S ex protected abstract void runTest(TestCaseGroupKey group_key, T test_case) throws IOException, Exception, Throwable; @Override - protected boolean slowCreateNewThread() { - return threads.size() < MAX_THREAD_COUNT; + protected boolean canCreateNewThread() { + return threads.size() < max_thread_count; } @Override diff --git a/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java b/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java index 6fb0ba0..8628a06 100644 --- a/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java +++ b/src/com/mostc/pftt/runner/AbstractPhpUnitTestCaseRunner.java @@ -274,7 +274,7 @@ public abstract class AbstractPhpUnitTestCaseRunner extends AbstractTestCaseRunn } // - if (is_timeout) { + if (is_timeout&&status!=EPhpUnitTestStatus.PASS) { status = EPhpUnitTestStatus.TIMEOUT; } else if (status==null) { // if test had a 'Fatal Error', it might not have been able to print the status code at all diff --git a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java index 2580f56..31d2cfd 100644 --- a/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java +++ b/src/com/mostc/pftt/runner/AbstractPhptTestCaseRunner2.java @@ -15,6 +15,7 @@ import org.incava.util.diff.Diff; import com.github.mattficken.io.StringUtil; import com.mostc.pftt.host.AHost; +import com.mostc.pftt.model.app.PhpUnitTemplate; import com.mostc.pftt.model.core.EPhptSection; import com.mostc.pftt.model.core.EPhptTestStatus; import com.mostc.pftt.model.core.PhpBuild; @@ -26,6 +27,7 @@ import com.mostc.pftt.model.core.PhptTestCase; import com.mostc.pftt.results.ConsoleManager; import com.mostc.pftt.results.ITestResultReceiver; import com.mostc.pftt.results.PhptTestResult; +import com.mostc.pftt.results.TestCaseCodeCoverage; import com.mostc.pftt.runner.LocalPhptTestPackRunner.PhptThread; import com.mostc.pftt.scenario.SAPIScenario; import com.mostc.pftt.scenario.ScenarioSetSetup; @@ -44,6 +46,8 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu protected final PhptThread thread; protected final SAPIScenario sapi_scenario; protected final PhptActiveTestPack active_test_pack; + protected final boolean xdebug; + protected TestCaseCodeCoverage code_coverage; protected Map<String, String> env; protected byte[] stdin_post; protected String skipif_file, test_dir, base_file_name, test_file, test_clean, content_type; @@ -54,18 +58,7 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu protected boolean is_timeout = false; public abstract String getIniActual() throws Exception; - - protected String get_ini_get_all_path() throws IllegalStateException, IOException { - // ensure ini_get_all.php exists - // TODO temp 5/15 - should store this once only and delete it later - String ini_get_all_path = host.mktempname(getClass(), "ini_get_all.php"); - if (!host.exists(ini_get_all_path)) { - // TODO locking? - host.saveTextFile(ini_get_all_path, "<?php var_dump($argv);\nvar_dump(ini_get_all()); ?>"); - } - return ini_get_all_path; - } - + /** runs the test case and reports the results to the PhptTelemetryManager * * @see #willSkip - called by PhptTestPackRunner before #runTest is called @@ -84,19 +77,44 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu prepareTest(); // String test_output = executeTest(); + // + if (xdebug) { + // read and filter code coverage data from the output + // @see PhpUnitTemplate#renderXDebugPhptTemplate + StringBuilder sb = new StringBuilder(4096); + code_coverage = new TestCaseCodeCoverage(host, test_file); + String filename = test_file; // can assume it starts here + for ( String line : StringUtil.splitLines(test_output)) { + if (line.startsWith("exe=")) { + code_coverage.addExecutedLine(filename, Integer.parseInt(line.substring("exe=".length()))); + } else if (line.startsWith("didnt_exe=")) { + code_coverage.addNotExecutedLine(filename, Integer.parseInt(line.substring("didnt_exe=".length()))); + } else if (line.startsWith("no_exe=")) { + code_coverage.addNonExecutableLine(filename, Integer.parseInt(line.substring("no_exe=".length()))); + } else if (line.startsWith("file=")) { + filename = line.substring("file=".length()); + } else { + sb.append(line); + sb.append('\n'); + } + } + test_output = sb.toString(); + } + // if (not_crashed) { // evalTest(test_output, test_case.getCommonCharset()); // some tests create files/dirs which, which will cause the test to fail again // if its run in-place from the same test-pack - if (!cm.isPhptNotInPlace()&&test_clean!=null) { + if (!cm.isPhptNotInPlace()&&test_clean!=null&&!host.isBusy()) { current_section = EPhptSection.CLEAN; // @see #getSAPIOutput executeClean(); // #executeClean != #doRunTestClean } } } - doRunTestClean(cm); + if (!host.isBusy()) + doRunTestClean(cm); } protected void doRunTestClean(ConsoleManager cm) throws IllegalStateException, IOException { @@ -120,7 +138,8 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu } } - public AbstractPhptTestCaseRunner2(SAPIScenario sapi_scenario, PhpIni ini, PhptThread thread, PhptTestCase test_case, ConsoleManager cm, ITestResultReceiver twriter, AHost host, ScenarioSetSetup scenario_set, PhpBuild build, PhptSourceTestPack src_test_pack, PhptActiveTestPack active_test_pack) { + public AbstractPhptTestCaseRunner2(boolean xdebug, SAPIScenario sapi_scenario, PhpIni ini, PhptThread thread, PhptTestCase test_case, ConsoleManager cm, ITestResultReceiver twriter, AHost host, ScenarioSetSetup scenario_set, PhpBuild build, PhptSourceTestPack src_test_pack, PhptActiveTestPack active_test_pack) { + this.xdebug = xdebug; this.sapi_scenario = sapi_scenario; this.ini = ini; this.thread = thread; @@ -209,7 +228,7 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu // // find 'skip ' or 'skip...' or 'skip.. ' or 'skip' but ignore '404 error, file not found abc.skip.php' // (don't need to check for multiple occurences of 'skip', just one... finding abc.skip.php would be a TEST_EXCEPTION or FAIL anyway) - if (lc_output.contains("skip") && ( !( this instanceof HttpPhptTestCaseRunner ) || !lc_output.contains("404")) ) { + if ((is_timeout||lc_output.contains("skip")) && ( !( this instanceof HttpPhptTestCaseRunner ) || !lc_output.contains("404")) ) { // test is to be skipped // decide to mark test SKIP or XSKIP (could test be executed on this OS?) @@ -217,15 +236,15 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu if (host.isWindows()) { if ( (lc_output.contains("only ")&&(lc_output.contains(" linux")||lc_output.contains(" non windows")||lc_output.contains(" non-windows")))||(lc_output.contains("not ")&&lc_output.contains(" windows"))) // can"t run this test on this OS - twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, is_timeout?EPhptTestStatus.TIMEOUT:EPhptTestStatus.XSKIP, test_case, output, null, null, null, ini, null, null, null, null, null, null, null)); + twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, EPhptTestStatus.XSKIP, test_case, output, null, null, null, ini, null, null, null, null, null, null, null)); else - twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, is_timeout?EPhptTestStatus.TIMEOUT:EPhptTestStatus.SKIP, test_case, output, null, null, null, ini, null, null, null, null, null, null, null)); + twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, EPhptTestStatus.SKIP, test_case, output, null, null, null, ini, null, null, null, null, null, null, null)); } else { if ( (lc_output.contains("only ")&&lc_output.contains(" windows"))||(lc_output.contains("not ")&&lc_output.contains(" linux"))) // can"t run this test on this OS - twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, is_timeout?EPhptTestStatus.TIMEOUT:EPhptTestStatus.XSKIP, test_case, output, null, null, null, ini, null, null, null, null, null, null, null)); + twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, EPhptTestStatus.XSKIP, test_case, output, null, null, null, ini, null, null, null, null, null, null, null)); else - twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, is_timeout?EPhptTestStatus.TIMEOUT:EPhptTestStatus.SKIP, test_case, output, null, null, null, ini, null, null, null, null, null, null, null)); + twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, EPhptTestStatus.SKIP, test_case, output, null, null, null, ini, null, null, null, null, null, null, null)); } // skip this test @@ -237,8 +256,10 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu } // end protected void evalSkipIf protected String preparePhptTestCode(String php_code) { - // TODO "<? xdebug_() ?>"; - return php_code; + if (xdebug) + return PhpUnitTemplate.renderXDebugPhptTemplate(php_code); + else + return php_code; } static final Pattern PATTERN_CONTENT_TYPE = Pattern.compile("Content-Type:(.*)"); @@ -447,12 +468,12 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu try { expected_re_match = test_case.getExpectedCompiled(host, scenario_set, twriter, false).match(output_trim); } catch (Throwable ex) { - twriter.addTestException(host, scenario_set, test_case, ex, expected); + twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, EPhptTestStatus.BORK, test_case, ErrorUtil.toString(ex), null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage)); throw ex; } if (expected_re_match) { - twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig()))); + twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage))); return; } @@ -460,12 +481,12 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu try { expected_re_match = test_case.getExpectedCompiled(host, scenario_set, twriter, true).match(output_trim); } catch (Throwable ex) { - twriter.addTestException(host, scenario_set, test_case, ex, expected); + twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, EPhptTestStatus.BORK, test_case, ErrorUtil.toString(ex), null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage)); throw ex; } if (expected_re_match) { - twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig()))); + twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage))); return; } @@ -483,12 +504,12 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu try { expected_re_match = test_case.getExpectedCompiled(host, scenario_set, twriter, false).match(output_trim); } catch (Throwable ex) { - twriter.addTestException(host, scenario_set, test_case, ex, expected); + twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, EPhptTestStatus.BORK, test_case, ErrorUtil.toString(ex), null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage)); throw ex; } if (expected_re_match) { - twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig()))); + twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage))); return; } @@ -496,12 +517,12 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu try { expected_re_match = test_case.getExpectedCompiled(host, scenario_set, twriter, true).match(output_trim); } catch (Throwable ex) { - twriter.addTestException(host, scenario_set, test_case, ex, expected); + twriter.addResult(host, scenario_set, src_test_pack, new PhptTestResult(host, EPhptTestStatus.BORK, test_case, ErrorUtil.toString(ex), null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage)); throw ex; } if (expected_re_match) { - twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig()))); + twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage))); return; } @@ -514,7 +535,7 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu if (equalsNoWS(output, expected)||(test_case.expectsWarningOrFatalError() && equalsNoWS(output, PhptTestCase.removeWarningAndFatalError(expected)))||(output.contains("<html>")&&!output.contains("404"))||(test_case.isNamed("ext/phar/tests/zip/phar_commitwrite.phpt")&&expected.contains(output.substring(50, 60)))||(test_case.isNamed("ext/phar/tests/tar/phar_commitwrite.phpt")&&expected.contains(output.substring(60, 70)))) { - twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(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))); + twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(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, code_coverage))); return; } @@ -531,7 +552,7 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu // compare again if (equalsNoWS(output, expected)) { - twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig()))); + twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage))); return; } // end if @@ -541,7 +562,7 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu String output_trim = output.trim(); if (StringUtil.isEmpty(output_trim)||(output.contains("<html>")&&!output.contains("404"))) { - twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig()))); + twriter.addResult(host, scenario_set, src_test_pack, notifyPassOrXFail(new PhptTestResult(host, test_case.isXFail()?EPhptTestStatus.XFAIL:EPhptTestStatus.PASS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage))); return; } @@ -564,9 +585,9 @@ public abstract class AbstractPhptTestCaseRunner2 extends AbstractPhptTestCaseRu PhptTestResult result; if (test_case.isXFail()) { - result = notifyNotPass(new PhptTestResult(host, is_timeout?EPhptTestStatus.TIMEOUT:EPhptTestStatus.XFAIL_WORKS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig())); + result = notifyNotPass(new PhptTestResult(host, is_timeout?EPhptTestStatus.TIMEOUT:EPhptTestStatus.XFAIL_WORKS, test_case, output, null, null, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), null, null, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage)); } else { - result = notifyNotPass(notifyFail(new PhptTestResult(host, is_timeout?EPhptTestStatus.TIMEOUT:EPhptTestStatus.FAIL, test_case, output, actual_lines, expected_lines, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), diff, expectf, preoverride_actual, getSAPIOutput(), getSAPIConfig()))); + result = notifyNotPass(notifyFail(new PhptTestResult(host, is_timeout?EPhptTestStatus.TIMEOUT:EPhptTestStatus.FAIL, test_case, output, actual_lines, expected_lines, charset, ini, env, splitCmdString(), stdin_post, getShellScript(), diff, expectf, preoverride_actual, getSAPIOutput(), getSAPIConfig(), code_coverage))); } // diff --git a/src/com/mostc/pftt/runner/AbstractTestPackRunner.java b/src/com/mostc/pftt/runner/AbstractTestPackRunner.java index d3595df..ab2a72e 100644 --- a/src/com/mostc/pftt/runner/AbstractTestPackRunner.java +++ b/src/com/mostc/pftt/runner/AbstractTestPackRunner.java @@ -56,12 +56,12 @@ public abstract class AbstractTestPackRunner<S extends SourceTestPack<?, T>, T e public abstract class SlowReplacementTestPackRunnerThread extends TestPackRunnerThread { - protected abstract boolean slowCreateNewThread(); + protected abstract boolean canCreateNewThread(); protected abstract void createNewThread(); @Override public void notifySlowTest() { - if (slowCreateNewThread()) { + if (canCreateNewThread()) { createNewThread(); } }