Commit: d718fd0f726cc04289b74f3a7ec3466d0a79ad9b
Author: Matt Ficken <mattfic...@php.net> Wed, 20 Jun 2018 19:36:17
-0700
Parents: a6b3e5b47bdd498fb3255059de6b2425a3ba7f58
Branches: master
Link:
http://git.php.net/?p=pftt2.git;a=commitdiff;h=d718fd0f726cc04289b74f3a7ec3466d0a79ad9b
Log:
updates for Azure App Services, Nanoserver and other changes
Changed paths:
A bin/NanoServerApiScan.exe
A src/com/mostc/pftt/model/ApplicationSourceTestPack.java
A src/com/mostc/pftt/model/app/AppUnitTestCase.java
A src/com/mostc/pftt/model/sapi/GenericWebServerManager.java
A src/com/mostc/pftt/runner/AbstractApplicationUnitTestCaseRunner.java
A src/com/mostc/pftt/runner/CliSimpleTestCaseRunner.java
A src/com/mostc/pftt/runner/HttpSimpleTestCaseRunner.java
A src/com/mostc/pftt/runner/LocalSimpleTestPackRunner.java
diff --git a/bin/NanoServerApiScan.exe b/bin/NanoServerApiScan.exe
new file mode 100644
index 0000000..4fbbea9
Binary files /dev/null and b/bin/NanoServerApiScan.exe differ
diff --git a/src/com/mostc/pftt/model/ApplicationSourceTestPack.java
b/src/com/mostc/pftt/model/ApplicationSourceTestPack.java
new file mode 100644
index 0000000..ce4a290
--- /dev/null
+++ b/src/com/mostc/pftt/model/ApplicationSourceTestPack.java
@@ -0,0 +1,155 @@
+package com.mostc.pftt.model;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.annotation.Nullable;
+
+import com.github.mattficken.Overridable;
+import com.github.mattficken.io.StringUtil;
+import com.mostc.pftt.host.AHost;
+import com.mostc.pftt.host.LocalHost;
+import com.mostc.pftt.model.core.EBuildBranch;
+import com.mostc.pftt.results.ConsoleManager;
+import com.mostc.pftt.scenario.AzureWebsitesScenario;
+import com.mostc.pftt.scenario.FileSystemScenario;
+import com.mostc.pftt.scenario.SAPIScenario;
+
+public abstract class ApplicationSourceTestPack<A extends ActiveTestPack, T
extends TestCase> extends SourceTestPack<A,T> {
+ protected String test_pack_root;
+
+ /** installs the tests after they have been copied to storage (if
needed)
+ *
+ * @see #getRoot() returns the location the tests and their php files
have been copied to (if they were
+ * copied, if not copied, returns location they are stored at)
+ *
+ * @param cm
+ * @param host
+ * @return
+ * @throws Exception
+ */
+ protected abstract boolean openAfterInstall(ConsoleManager cm, AHost
host) throws Exception;
+
+ /** the base directory within the PFTT directory to find the test case
files and required php files
+ *
+ * Typically, test-packs will call #ensureAppDecompressed
+ *
+ * @param cm
+ * @param host - determine the absolute path on this host
+ * @see AHost#getPfttDir
+ * @return
+ */
+ protected abstract String getSourceRoot(ConsoleManager cm, AHost host);
+
+ protected void doInstallInPlace(ConsoleManager cm, AHost host) throws
IOException, Exception {
+ final String src_root = getSourceRoot(cm,
LocalHost.getInstance());
+ if (!new File(src_root).isDirectory()) {
+ throw new IOException("source-test-pack not found:
"+src_root);
+ }
+ setRoot(src_root);
+
+ openAfterInstall(cm, host);
+ }
+
+ protected void doInstallNamed(ConsoleManager cm, AHost host) throws
IOException, Exception {
+ final String src_root = getSourceRoot(cm,
LocalHost.getInstance());
+ if (!new File(src_root).isDirectory()) {
+ throw new IOException("source-test-pack not found:
"+src_root);
+ }
+ setRoot(src_root);
+
+ openAfterInstall(cm, host);
+ }
+
+ protected void doInstall(SAPIScenario sapi_scenario, ConsoleManager cm,
AHost host, String local_test_pack_dir, String remote_test_pack_dir) throws
IOException, Exception {
+ LocalHost local_host = LocalHost.getInstance();
+ final String src_root = getSourceRoot(cm, local_host);
+ if (!new File(src_root).isDirectory()) {
+ throw new IOException("source-test-pack not found:
"+src_root);
+ }
+
+ // using #uploadCompressWith7Zip instead of just #upload makes
a huge difference
+ // for PhpUnit test-packs because of the large number of small
files that have to be uploaded
+ // TODO temp azure host.uploadCompressWith7Zip(cm, getClass(),
src_root, local_host, remote_test_pack_dir);
+ System.out.println("71 "+local_test_pack_dir);
+ //System.exit(0);
+
+ if (AzureWebsitesScenario.check(sapi_scenario)) {
+
setRoot("D:\\HOME\\SITE\\WWWROOT\\"+FileSystemScenario.basename(getName()).replace("-12.3",
"").replace("-1.20.2", ""));//MEDIAWIKI");//local_test_pack_dir);
+ } else {
+ setRoot(src_root);// TODO temp azure ??
local_test_pack_dir);
+ }
+
+ openAfterInstall(cm, local_host);
+ }
+
+ private boolean decompressed = false;
+ protected void ensureAppDecompressed(ConsoleManager cm, AHost host,
String zip7_file) throws IllegalStateException, IOException, Exception {
+ if (decompressed)
+ return;
+ decompressed = true;
+ if (!StringUtil.endsWithIC(zip7_file, ".7z"))
+ zip7_file += ".7z";
+
+ // TODO temp azure host.decompress(cm, host,
host.getPfttDir()+"/app/"+zip7_file, host.getPfttDir()+"/cache/working/");
+ }
+
+ /** Sometimes there are multiple tests that share a common resource
(such as a file directory
+ * or database) and can not be run at the same time. Such tests are
non-thread-safe (known as NTS tests).
+ *
+ * Return the full or partial filenames of NTS tests here. The returned
array is processed in
+ * order. If any string from the same string array matches, all tests
matching that array will
+ * be run in the same thread.
+ *
+ * @return
+ */
+ @Nullable
+ public String[][] getNonThreadSafeTestFileNames() {
+ return null;
+ }
+
+ public String getName() {
+ return getNameAndVersionString();
+ }
+
+ /** file path to test-pack */
+ public void setRoot(String test_pack_root) {
+ this.test_pack_root = test_pack_root;
+ }
+ @Override
+ public String getSourceDirectory() {
+ return getRoot();
+ }
+ /** file path to test-pack */
+ public String getRoot() {
+ return this.test_pack_root;
+ }
+
+ /** TRUE if test-pack is 'under development'. FALSE if its stable.
+ *
+ * test runner will include extra info(stack traces, etc...) for
test-packs that are under development
+ *
+ * @return
+ */
+ @Overridable
+ public boolean isDevelopment() {
+ return false;
+ }
+
+ @Override
+ public EBuildBranch getTestPackBranch() {
+ return null;
+ }
+
+ @Override
+ public String getTestPackVersionRevision() {
+ return getNameAndVersionString();
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+
+} // end public abstract class ApplicationSourceTestPack
+
\ No newline at end of file
diff --git a/src/com/mostc/pftt/model/app/AppUnitTestCase.java
b/src/com/mostc/pftt/model/app/AppUnitTestCase.java
new file mode 100644
index 0000000..707620c
--- /dev/null
+++ b/src/com/mostc/pftt/model/app/AppUnitTestCase.java
@@ -0,0 +1,77 @@
+package com.mostc.pftt.model.app;
+
+import com.github.mattficken.io.StringUtil;
+import com.mostc.pftt.model.TestCase;
+import com.mostc.pftt.scenario.FileSystemScenario;
+
+public abstract class AppUnitTestCase extends TestCase {
+ protected final String rel_filename, abs_filename;
+
+ public AppUnitTestCase(String rel_filename, String abs_filename) {
+ this.rel_filename = rel_filename;
+ // don't need to call #normalizeFilename here usually. it's
called in PhpUnitSourcetestPack#readDir...
+ // calling it (again )here would be a performance hit
+ this.abs_filename = abs_filename;
+ }
+
+ public boolean fileNameStartsWithAny(String[] ext_names) {
+ return StringUtil.startsWithAnyIC(getFileName(), ext_names);
+ }
+
+ /** name of file.
+ *
+ * file is case preserved to avoid breaking posix.
+ *
+ * windows slashes \\ are standardized to / posix.
+ *
+ * for case-insensitive matching @see #isFileName or @see
#fileNameStartsWithAny
+ *
+ * @return
+ */
+ public String getFileName() {
+ return rel_filename;
+ }
+
+ public String getAbsoluteFileName() {
+ return abs_filename;
+ }
+
+ public boolean isFileName(String file_name) {
+ return
this.rel_filename.toLowerCase().equals(file_name.toLowerCase())
+ ||
this.abs_filename.toLowerCase().equals(file_name.toLowerCase());
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o==this)
+ return true;
+ else if (o instanceof AppUnitTestCase)
+ return o.toString().equals(this.toString());
+ else
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return getName().hashCode();
+ }
+
+ /** fixes slashes to Posix forward slash /.
+ *
+ * this is case-preserving (to avoid breaking on posix). case is not
changed.
+ *
+ * to do case-insenstive matching @see #isFileName
+ *
+ * @param test_name
+ * @return
+ */
+ public static String normalizeFileName(String test_name) {
+ return FileSystemScenario.toUnixPath(test_name);
+ }
+
+} // end public abstract class AppUnitTestCase
diff --git a/src/com/mostc/pftt/model/sapi/GenericWebServerManager.java
b/src/com/mostc/pftt/model/sapi/GenericWebServerManager.java
new file mode 100644
index 0000000..8c97afa
--- /dev/null
+++ b/src/com/mostc/pftt/model/sapi/GenericWebServerManager.java
@@ -0,0 +1,74 @@
+package com.mostc.pftt.model.sapi;
+
+import java.util.Map;
+
+import com.mostc.pftt.host.AHost;
+import com.mostc.pftt.model.core.PhpIni;
+import com.mostc.pftt.scenario.FileSystemScenario;
+
+public class GenericWebServerManager extends UnmanagedWebServerManager {
+ protected final String hostname, web_server_software, docroot;
+ protected final int port;
+ protected final boolean ssl;
+
+ public GenericWebServerManager(String hostname, int port, String
docroot, String web_server_software, boolean ssl) {
+ if (port<1)
+ port = 80;
+
+ this.hostname = hostname;
+ this.port = port;
+ this.docroot = docroot;
+ this.web_server_software = web_server_software;
+ this.ssl = ssl;
+ }
+
+ public GenericWebServerManager(String hostname, int port, String
docroot, String web_server_software) {
+ this(hostname, port, docroot, web_server_software, false);
+ }
+
+ @Override
+ protected UnmanagedWebServerInstance createUnmanagedWebServerInstance()
{
+ return new GenericWebServerInstance(null, null, null, null,
null, null);
+ }
+
+ protected class GenericWebServerInstance extends
UnmanagedWebServerInstance {
+
+ public GenericWebServerInstance(FileSystemScenario fs, AHost
host,
+ WebServerManager ws_mgr, String[] cmd_array,
PhpIni ini,
+ Map<String, String> env) {
+ super(fs, host, ws_mgr, cmd_array, ini, env);
+ }
+
+ @Override
+ public String getName() {
+ return web_server_software;
+ }
+
+ @Override
+ public String getHostname() {
+ return hostname;
+ }
+
+ @Override
+ public int getPort() {
+ return port;
+ }
+
+ @Override
+ public String getDocroot() {
+ return docroot;
+ }
+
+ }
+
+ @Override
+ public String getName() {
+ return "Generic-Web-Server";
+ }
+
+ @Override
+ public boolean isSSLSupported() {
+ return ssl;
+ }
+
+}
diff --git
a/src/com/mostc/pftt/runner/AbstractApplicationUnitTestCaseRunner.java
b/src/com/mostc/pftt/runner/AbstractApplicationUnitTestCaseRunner.java
new file mode 100644
index 0000000..730d06a
--- /dev/null
+++ b/src/com/mostc/pftt/runner/AbstractApplicationUnitTestCaseRunner.java
@@ -0,0 +1,34 @@
+package com.mostc.pftt.runner;
+
+import java.util.regex.Pattern;
+
+import com.mostc.pftt.host.AHost;
+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.ITestResultReceiver;
+import com.mostc.pftt.runner.AbstractLocalTestPackRunner.TestPackThread;
+import com.mostc.pftt.scenario.FileSystemScenario;
+import com.mostc.pftt.scenario.SAPIScenario;
+import com.mostc.pftt.scenario.ScenarioSetSetup;
+
+public abstract class AbstractApplicationUnitTestCaseRunner<T extends
TestPackThread,R extends AbstractLocalTestPackRunner> extends
AbstractTestCaseRunner<T,R> {
+ protected final T thread;
+ protected boolean is_crashed, is_timeout;
+
+ 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_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.*");
+ }
+
+ public AbstractApplicationUnitTestCaseRunner(FileSystemScenario fs,
SAPIScenario sapi_scenario, T thread, ITestResultReceiver twriter,
ConsoleManager cm, AHost host, ScenarioSetSetup scenario_set, PhpBuild build,
PhpIni ini) {
+ super(fs, sapi_scenario, twriter, cm, host, scenario_set,
build, ini);
+ this.thread = thread;
+ }
+
+ protected abstract String generatePhpScript();
+
+} // end public abstract class AbstractApplicationUnitTestCaseRunner
diff --git a/src/com/mostc/pftt/runner/CliSimpleTestCaseRunner.java
b/src/com/mostc/pftt/runner/CliSimpleTestCaseRunner.java
new file mode 100644
index 0000000..b104c52
--- /dev/null
+++ b/src/com/mostc/pftt/runner/CliSimpleTestCaseRunner.java
@@ -0,0 +1,100 @@
+package com.mostc.pftt.runner;
+
+import java.io.IOException;
+
+import com.github.mattficken.io.IOUtil;
+import com.mostc.pftt.host.AHost;
+import com.mostc.pftt.host.AHost.ExecHandle;
+import com.mostc.pftt.model.app.SimpleTestCase;
+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.ITestResultReceiver;
+import com.mostc.pftt.runner.LocalSimpleTestPackRunner.SimpleTestThread;
+import com.mostc.pftt.scenario.FileSystemScenario;
+import com.mostc.pftt.scenario.SAPIScenario;
+import com.mostc.pftt.scenario.ScenarioSetSetup;
+import com.mostc.pftt.util.NTStatus;
+
+public class CliSimpleTestCaseRunner extends AbstractSimpleTestCaseRunner {
+ protected ExecHandle running_test_handle;
+ protected String output_str;
+
+ public CliSimpleTestCaseRunner(FileSystemScenario fs, SAPIScenario
sapi_scenario, SimpleTestThread thread, ITestResultReceiver tmgr,
ConsoleManager cm, AHost host, ScenarioSetSetup scenario_set, PhpBuild build,
PhpIni ini, SimpleTestCase test_case) {
+ super(fs, sapi_scenario, thread, tmgr, cm, host, scenario_set,
build, ini, test_case);
+ }
+
+ @Override
+ public String getSAPIOutput() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getSAPIConfig() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ //@Override
+ protected void stop(boolean force) {
+ if (running_test_handle==null)
+ return;
+ running_test_handle.close(cm, force);
+ }
+
+ private void doExecute(String template_file, String ini_dir) throws
Exception {
+ template_file = fs.fixPath(template_file);
+
+ String cmd = build.getPhpExe()+" "+template_file;
+ System.out.println("49 "+cmd);
+ running_test_handle = host.execThread(
+ //build.getPhpExe()+" -c "+ini_dir+"
"+template_file//,
+ build.getPhpExe()+" "+template_file//,
+ //env,
+
//test_case.getPhpUnitDist().getPath().getAbsolutePath()
+ );
+
+ StringBuilder output_sb = new StringBuilder(128);
+ System.out.println(output_sb);
+ running_test_handle.run(
+ cm,
+ output_sb,
+ null,
+
SimpleTestCase.MAX_TEST_TIME_SECONDS,//getMaxTestRuntimeSeconds(),
+ null,
+ 0, cm.getSuspendSeconds(),
+ IOUtil.HALF_MEGABYTE
+ );
+
+ output_str = output_sb.toString();
+
+ is_crashed = running_test_handle.isCrashed();
+ is_timeout = running_test_handle.isTimedOut();
+ }
+
+ @Override
+ protected String execute(String template_file) throws IOException,
Exception {
+ final String ini_dir = build.prepare(cm, fs, host); // XXX
store PhpIni in my_temp_dir ?
+
+ doExecute(template_file, ini_dir);
+ if (is_crashed && running_test_handle.getExitCode() != -2
+ && running_test_handle.getExitCode() !=
NTStatus.STATUS_ACCESS_VIOLATION) {
+ // try a second time to be sure
+ is_crashed = false;
+
+ doExecute(template_file, ini_dir);
+ }
+
+ if (is_crashed) {
+ int exit_code = running_test_handle.getExitCode();
+
+ output_str += "PFTT: crashed: exit_code="+exit_code+"
status="+AHost.guessExitCodeStatus(host, exit_code);
+ }
+
+ running_test_handle = null;
+
+ return output_str;
+ }
+
+}
diff --git a/src/com/mostc/pftt/runner/HttpSimpleTestCaseRunner.java
b/src/com/mostc/pftt/runner/HttpSimpleTestCaseRunner.java
new file mode 100644
index 0000000..975a97c
--- /dev/null
+++ b/src/com/mostc/pftt/runner/HttpSimpleTestCaseRunner.java
@@ -0,0 +1,42 @@
+package com.mostc.pftt.runner;
+
+import java.io.IOException;
+
+import com.mostc.pftt.host.AHost;
+import com.mostc.pftt.model.app.SimpleTestCase;
+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.ITestResultReceiver;
+import com.mostc.pftt.runner.LocalSimpleTestPackRunner.SimpleTestThread;
+import com.mostc.pftt.scenario.FileSystemScenario;
+import com.mostc.pftt.scenario.SAPIScenario;
+import com.mostc.pftt.scenario.ScenarioSetSetup;
+
+public class HttpSimpleTestCaseRunner extends AbstractSimpleTestCaseRunner {
+
+ public HttpSimpleTestCaseRunner(FileSystemScenario fs, SAPIScenario
sapi_scenario, SimpleTestThread thread, ITestResultReceiver tmgr,
ConsoleManager cm, AHost host, ScenarioSetSetup scenario_set, PhpBuild build,
PhpIni ini, SimpleTestCase test_case) {
+ super(fs, sapi_scenario, thread, tmgr, cm, host, scenario_set,
build, ini, test_case);
+ }
+
+ @Override
+ public String getSAPIOutput() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getSAPIConfig() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ protected String execute(String template_file) throws IOException,
+ Exception {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+}
diff --git a/src/com/mostc/pftt/runner/LocalSimpleTestPackRunner.java
b/src/com/mostc/pftt/runner/LocalSimpleTestPackRunner.java
new file mode 100644
index 0000000..2e8f331
--- /dev/null
+++ b/src/com/mostc/pftt/runner/LocalSimpleTestPackRunner.java
@@ -0,0 +1,81 @@
+package com.mostc.pftt.runner;
+
+import java.io.IOException;
+import java.util.Map;
+
+import com.mostc.pftt.host.AHost;
+import com.mostc.pftt.model.app.SimpleTestActiveTestPack;
+import com.mostc.pftt.model.app.SimpleTestCase;
+import com.mostc.pftt.model.app.SimpleTestSourceTestPack;
+import com.mostc.pftt.model.core.PhpBuild;
+import com.mostc.pftt.model.core.PhpIni;
+import com.mostc.pftt.model.sapi.TestCaseGroupKey;
+import com.mostc.pftt.results.LocalConsoleManager;
+import com.mostc.pftt.results.PhpResultPackWriter;
+import com.mostc.pftt.scenario.IScenarioSetup;
+import com.mostc.pftt.scenario.ScenarioSet;
+
+public class LocalSimpleTestPackRunner extends
AbstractLocalApplicationTestPackRunner<SimpleTestActiveTestPack,
SimpleTestSourceTestPack, SimpleTestCase> {
+
+ public LocalSimpleTestPackRunner(LocalConsoleManager cm,
+ PhpResultPackWriter tmgr, ScenarioSet scenario_set,
PhpBuild build,
+ AHost host, AHost host2) {
+ super(cm, tmgr, scenario_set, build, host, host2);
+ }
+
+ @Override
+ protected void showTally() {
+
+ }
+
+ @Override
+ protected boolean tryPrepare(PhpIni ini) {
+ return true;
+ }
+
+ @Override
+ protected TestPackThread<SimpleTestCase> createTestPackThread(boolean
parallel) throws IllegalStateException, IOException {
+ return new SimpleTestThread(parallel);
+ }
+
+ public class SimpleTestThread extends TestPackThread<SimpleTestCase> {
+
+ protected SimpleTestThread(boolean parallel) {
+ super(parallel);
+ }
+
+ @Override
+ protected void prepareExec(TestCaseGroupKey group_key, PhpIni
ini, Map<String, String> env, IScenarioSetup s) {
+ }
+
+ @Override
+ protected void runTest(TestCaseGroupKey group_key,
SimpleTestCase test_case, boolean debugger_attached) throws IOException,
Exception, Throwable {
+ sapi_scenario.createSimpleTestCaseRunner(
+ this,
+ twriter,
+ cm,
+ runner_fs,
+ runner_host,
+ scenario_set_setup,
+ build,
+ group_key.getPhpIni(), test_case
+ ).runTest(cm, this,
LocalSimpleTestPackRunner.this);
+ }
+
+ @Override
+ protected void stopRunningCurrentTest() {
+ }
+
+ @Override
+ protected int getMaxTestRuntimeSeconds() {
+ return SimpleTestCase.MAX_TEST_TIME_SECONDS;
+ }
+
+ @Override
+ protected void recordSkipped(SimpleTestCase test_case) {
+
+ }
+
+ } // end public class SimpleTestThread
+
+} // end public class LocalSimpleTestPackRunner
--
PHP Quality Assurance Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php