Commit: c20cec1c0a4eea3ea4edfa2c22552f7d4aa57ee5
Author: Matt Ficken <[email protected]> Wed, 20 Nov 2013
12:36:19 -0800
Parents: 12b8407317b4abd66116e9c5ccd1f796d9818096
Branches: master
Link:
http://git.php.net/?p=pftt2.git;a=commitdiff;h=c20cec1c0a4eea3ea4edfa2c22552f7d4aa57ee5
Log:
Time Travel Tracing integration (Windows only)
Former-commit-id: 1c507b3440740050eb6a11e8f07b4b42646d478f
Changed paths:
M conf/task/snap_test.groovy
M src/com/mostc/pftt/host/AHost.java
M src/com/mostc/pftt/host/ExecOutput.java
A src/com/mostc/pftt/host/ICrashDetector.java
M src/com/mostc/pftt/host/LocalHost.java
M src/com/mostc/pftt/host/PosixLocalHost.java
M src/com/mostc/pftt/host/WindowsLocalHost.java
A src/com/mostc/pftt/main/CmpReport.java
A src/com/mostc/pftt/main/CmpReport2.java
A src/com/mostc/pftt/main/CmpReport2G.groovy
A src/com/mostc/pftt/main/PBCReportGen.groovy
M src/com/mostc/pftt/model/sapi/CliSAPIInstance.java
M src/com/mostc/pftt/results/AbstractPhpUnitRW.java
M src/com/mostc/pftt/results/AbstractPhptRW.java
M src/com/mostc/pftt/results/AbstractTestResultRW.java
M src/com/mostc/pftt/results/AbstractUITestRW.java
M src/com/mostc/pftt/results/LocalConsoleManager.java
M src/com/mostc/pftt/results/PhptResultWriter.java
M src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
M src/com/mostc/pftt/runner/LocalPhptTestPackRunner.java
M src/com/mostc/pftt/scenario/CLIScenario.java
M src/com/mostc/pftt/util/DebuggerManager.java
M src/com/mostc/pftt/util/GDBDebugManager.java
A src/com/mostc/pftt/util/TimeTravelTraceDebugManager.java
M src/com/mostc/pftt/util/TimerUtil.java
M src/com/mostc/pftt/util/ValgrindMemoryCheckManager.java
M src/com/mostc/pftt/util/WinDebugManager.java
A src/com/mostc/pftt/util/WindowsDebuggerToolsManager.java
diff --git a/conf/task/snap_test.groovy b/conf/task/snap_test.groovy
index 06e5468..08a94e4 100644
--- a/conf/task/snap_test.groovy
+++ b/conf/task/snap_test.groovy
@@ -8,7 +8,7 @@ def processConsoleOptions(List options) {
//
options.add("-c")
// test these SAPIs
- options.add("apache,cli")//,builtin_web")
+ options.add("apache,cli")
options.add("-c")
// test with and without opcache
options.add("opcache,no_code_cache,not_opcache_builtin_web")
diff --git a/src/com/mostc/pftt/host/AHost.java
b/src/com/mostc/pftt/host/AHost.java
index e9adfc4..e37a3ba 100644
--- a/src/com/mostc/pftt/host/AHost.java
+++ b/src/com/mostc/pftt/host/AHost.java
@@ -15,6 +15,7 @@ import com.github.mattficken.io.ByLineReader;
import com.github.mattficken.io.CharsetDeciderDecoder;
import com.github.mattficken.io.IOUtil;
import com.github.mattficken.io.StringUtil;
+import com.mostc.pftt.results.AbstractTestResultRW;
import com.mostc.pftt.results.ConsoleManager;
import com.mostc.pftt.results.EPrintType;
import com.mostc.pftt.runner.AbstractTestPackRunner.TestPackRunnerThread;
@@ -390,8 +391,18 @@ public abstract class AHost extends Host implements
IProgramRunner {
public ExecOutput execElevatedOut(String cmd, int timeout_sec, String
chdir) throws Exception {
return execElevatedOut(cmd, timeout_sec, chdir, false);
}
+ public interface IExecHandleCleanupNotify {
+ public void cleanupNotify(ExecHandle eh, AbstractTestResultRW
rw);
+ }
@ThreadSafe
- public abstract class ExecHandle {
+ public abstract class ExecHandle implements ICrashDetector {
+ public IExecHandleCleanupNotify cleanup_notify;
+ public void cleanup(AbstractTestResultRW rw) {
+ if (cleanup_notify==null)
+ return;
+
+ cleanup_notify.cleanupNotify(this, rw);
+ }
public abstract InputStream getSTDOUT();
public abstract OutputStream getSTDIN();
/** KILLs process
@@ -423,6 +434,7 @@ public abstract class AHost extends Host implements
IProgramRunner {
*
* @return
*/
+ @Override
public boolean isCrashed() {
return isCrashExitCode(AHost.this, getExitCode(),
false);
}
diff --git a/src/com/mostc/pftt/host/ExecOutput.java
b/src/com/mostc/pftt/host/ExecOutput.java
index b2d49fb..a7f5b9b 100644
--- a/src/com/mostc/pftt/host/ExecOutput.java
+++ b/src/com/mostc/pftt/host/ExecOutput.java
@@ -7,7 +7,7 @@ import com.github.mattficken.io.StringUtil;
import com.mostc.pftt.results.ConsoleManager;
import com.mostc.pftt.results.EPrintType;
-public class ExecOutput {
+public class ExecOutput implements ICrashDetector {
/** output of executed program */
public String output;
/** character the program used for its output */
@@ -36,6 +36,7 @@ public class ExecOutput {
public boolean isSuccess() {
return exit_code == 0;
}
+ @Override
public boolean isCrashed() {
return exit_code < -1;
}
diff --git a/src/com/mostc/pftt/host/ICrashDetector.java
b/src/com/mostc/pftt/host/ICrashDetector.java
new file mode 100644
index 0000000..3851c64
--- /dev/null
+++ b/src/com/mostc/pftt/host/ICrashDetector.java
@@ -0,0 +1,5 @@
+package com.mostc.pftt.host;
+
+public interface ICrashDetector {
+ public boolean isCrashed();
+}
diff --git a/src/com/mostc/pftt/host/LocalHost.java
b/src/com/mostc/pftt/host/LocalHost.java
index 21e26fd..3ef655f 100644
--- a/src/com/mostc/pftt/host/LocalHost.java
+++ b/src/com/mostc/pftt/host/LocalHost.java
@@ -350,9 +350,9 @@ public abstract class LocalHost extends AHost {
return;
// @see WindowsLocalHost#exec_copy_lines
run.set(false);
- synchronized(run) {
+ /*synchronized(run) {
run.notifyAll();
- }
+ }*/
// sometimes it can take a while to #close a
process(especially on Windows)... do it in a thread
// to avoid blocking for too long. however, we don't
want to have too many threads
@@ -431,9 +431,13 @@ public abstract class LocalHost extends AHost {
// read process' output (block until #close or exit)
exec_copy_lines(output_sb, max_chars, stdout, charset);
// ignores STDERR
-
+ for(;;) {
+ if (!doIsRunning(p))
+ break;
+ Thread.sleep(50);
+ }
// wait for process exit (shouldn't get here until exit
or #close though)
- for (int time = 50;wait.get();) {
+ /*for (int time = 50;wait.get();) {
try {
exit_code = p.exitValue();
break;
@@ -458,7 +462,7 @@ public abstract class LocalHost extends AHost {
break;
}
}
- }
+ }*/
//
active_proc_counter.decrementAndGet();
@@ -511,10 +515,7 @@ public abstract class LocalHost extends AHost {
return exit_code;
}
- public int getProcessID() {
- final Process p = process.get();
- return p!=null && isLocalhostWindows() ?
getWindowsProcessID(p) : 0;
- }
+ public abstract int getProcessID();
@Override
public InputStream getSTDOUT() {
@@ -532,7 +533,8 @@ public abstract class LocalHost extends AHost {
public void run(ConsoleManager cm, StringBuilder output_sb,
Charset charset, int timeout_sec, @SuppressWarnings("rawtypes")
TestPackRunnerThread thread, int thread_slow_sec, int suspend_seconds, int
max_chars) throws IOException, InterruptedException {
TimerThread a = null, b = null;
if (thread!=null && thread_slow_sec>NO_TIMEOUT) {
- b = TimerUtil.waitSeconds(thread_slow_sec, new
ThreadSlowTask(thread));
+ // TODO get rid of thread_slow_sec feature -
just use AbstractLocalTestPackRunner
+ //b = TimerUtil.waitSeconds(thread_slow_sec,
new ThreadSlowTask(thread));
}
if (timeout_sec>NO_TIMEOUT) {
@@ -554,17 +556,6 @@ public abstract class LocalHost extends AHost {
} // end public class LocalExecHandle
- // TODO temp
- public static int getWindowsProcessID(Process process) {
- try {
- // clean way
- WinProcess wproc = new WinProcess(process);
- return wproc.getPid();
- } catch ( Throwable wt ) {
- return getWindowsProcessIDReflection(process);
- }
- }
-
protected static int getWindowsProcessIDReflection(Process process) {
// WinProcess native code couldn't be loaded
// (maybe it wasn't included or maybe somebody didn't compile
it)
diff --git a/src/com/mostc/pftt/host/PosixLocalHost.java
b/src/com/mostc/pftt/host/PosixLocalHost.java
index 0b14b30..60e59c3 100644
--- a/src/com/mostc/pftt/host/PosixLocalHost.java
+++ b/src/com/mostc/pftt/host/PosixLocalHost.java
@@ -40,6 +40,11 @@ public class PosixLocalHost extends LocalHost {
return doIsRunning(p);
}
+ public int getProcessID() {
+ final Process p = process.get();
+ return 0; // TODO
+ }
+
protected void exec_copy_lines(final StringBuilder sb, final
int max_chars, final InputStream in, final Charset charset) throws IOException {
do_exec_copy_lines(sb, max_chars, in, charset);
}
diff --git a/src/com/mostc/pftt/host/WindowsLocalHost.java
b/src/com/mostc/pftt/host/WindowsLocalHost.java
index 0c160bd..225936c 100644
--- a/src/com/mostc/pftt/host/WindowsLocalHost.java
+++ b/src/com/mostc/pftt/host/WindowsLocalHost.java
@@ -13,7 +13,6 @@ import org.jvnet.winp.WinProcess;
import com.github.mattficken.io.StringUtil;
import com.mostc.pftt.host.CommonCommandManager.Win32ProcessInfo;
-import com.mostc.pftt.main.PfttMain;
import com.mostc.pftt.runner.AbstractTestPackRunner.TestPackRunnerThread;
import com.mostc.pftt.util.TimerUtil;
import com.mostc.pftt.util.TimerUtil.ObjectRunnable;
@@ -93,11 +92,16 @@ public class WindowsLocalHost extends LocalHost {
// IMPORTANT: this is how its identified in the
Windows process table
this.image_name = "cmd.exe";
} else {
- this.image_name = this.image_name.toLowerCase();
- if (this.image_name.equals("cmd"))
- this.image_name = "cmd.exe";
+ this.image_name =
basename(this.image_name).toLowerCase();
+ if (image_name.indexOf('.')==-1)
+ this.image_name += ".exe";
}
}
+
+ public int getProcessID() {
+ final Process p = process.get();
+ return p!=null ? getWindowsProcessID(p) : 0;
+ }
@Override
public boolean isRunning() {
@@ -147,24 +151,31 @@ public class WindowsLocalHost extends LocalHost {
try {
do_exec_copy_lines(sb,
max_chars, in, charset);
copy_thread_lock.set(false);
- synchronized(run) {
+ run.set(false);
+ /*synchronized(run) {
run.notifyAll();
- }
- } catch (IOException e) {
- e.printStackTrace();
+ }*/
+ } catch (Throwable e) {
+ //e.printStackTrace();
}
}
});
copy_thread.setUncaughtExceptionHandler(IGNORE_EXCEPTION_HANDLER);
while (wait.get()) {
- synchronized(run) {
+ //synchronized(run) {
try {
- run.wait(30000);
+ //run.wait(30000);
+ Thread.sleep(300);
} catch ( InterruptedException ex ) {}
- }
+ //}
if (!run.get()) {
// try killing copy thread since its
still running after it was supposed to stop
- copy_thread.stop(new
RuntimeException());
+ copy_thread.stop(new RuntimeException()
{
+ @Override
+ public void printStackTrace() {
+
+ }
+ });
break;
} else if (!copy_thread_lock.get()) {
// stopped normally
@@ -208,7 +219,9 @@ public class WindowsLocalHost extends LocalHost {
// Windows BN?: if TerminateProcess() called with a PID
that doesn't exist anymore (but might again soon)
// does TerminateProcess() block forever
(or does it appear that way because of Windows slow process
// management?(Windows is optimized to run
a few processes only (because thats what users did with it in the '90s)))
- if
(image_name.equals("taskkill.exe")||image_name.equals("handle.exe")||image_name.equals("pskill.exe"))
{
+ String image_name = basename(this.image_name);
+ if
(image_name.equals("taskkill.exe")||image_name.equals("handle.exe")||image_name.equals("pskill.exe")
+
||image_name.equals("taskkill")||image_name.equals("handle")||image_name.equals("pskill"))
{
// can't use taskkill, could create an infinite
loop
//
// @see https://github.com/kohsuke/winp
@@ -220,12 +233,16 @@ public class WindowsLocalHost extends LocalHost {
int pid = getWindowsProcessIDReflection(p); // NOT
WinProcess#getPID?
// for closing handles and other special stuff to work
here, must get the actual process
// not just cmd.exe (it won't have problems with stray
handles, etc...)
- if (image_name.equals("cmd.exe")) {
+ //
+ // IMPORTANT: #doClose may be called multiple times, so
don't change this#doClose
+ if
(image_name.equals("cmd.exe")||image_name.equals("cmd")) {
List<Win32ProcessInfo> table =
ccm.getWindowsProcessTable(WindowsLocalHost.this);
for ( Win32ProcessInfo info : table ) {
if (info.parent_pid==pid) {
// found child
- image_name = info.exe_path;
+ //
+ // IMPORTANT: basename()
because TaskKill doesn't take paths for image name
+ image_name =
basename(info.exe_path);
pid = info.pid;
}
}
@@ -250,28 +267,23 @@ public class WindowsLocalHost extends LocalHost {
// @see
AbstractPhptTestCaseRunner2#doRunTestClean
ccm.winCloseAllHandles(WindowsLocalHost.this, pid);
}
- // can kill off windebug if running under PUTS
(windebug shouldn't be running at all, sometimes does)
- if (!PfttMain.is_puts &&
ccm.ensureWinDebugIsNotRunning(WindowsLocalHost.this, pid)) {
-
- // do nothing, wait for windebug
- } else {
- // provide TASKKILL the image name of
the process to try avoiding killing the wrong process
- try {
- // /T => terminate child
processes too
- exec("TASKKILL /FI \"IMAGENAME
eq "+image_name+"\" /FI \"PID eq "+pid+"\" /F /T", 20);
- // also,
WinProcess#killRecursively only checks by process id (not image/program name)
- // while that should be enough,
experience on Windows has shown that it isn't and somehow gets PFTT killed
eventually
- //
- // Windows Note: Windows does
NOT automatically terminate child processes when the parent gets killed
- // the only way
that happens is if you search for the child processes FIRST yourself,
- // (and then
their children, etc...) and then kill them.
- } catch ( Exception ex ) {
- // fallback
- //
- // @see
https://github.com/kohsuke/winp
- WinProcess wprocess = new
WinProcess(p);
- wprocess.kill();
- }
+ // provide TASKKILL the image name of the
process to try avoiding killing the wrong process
+ try {
+ // /T => terminate child processes too
+ exec("TASKKILL /FI \"IMAGENAME eq
"+image_name+"\" /FI \"PID eq "+pid+"\" /F /T", 20);
+ // also, WinProcess#killRecursively
only checks by process id (not image/program name)
+ // while that should be enough,
experience on Windows has shown that it isn't and somehow gets PFTT killed
eventually
+ //
+ // Windows Note: Windows does NOT
automatically terminate child processes when the parent gets killed
+ // the only way that
happens is if you search for the child processes FIRST yourself,
+ // (and then their
children, etc...) and then kill them.
+ } catch ( Exception ex ) {
+ ex.printStackTrace();
+ // fallback
+ //
+ // @see https://github.com/kohsuke/winp
+ WinProcess wprocess = new WinProcess(p);
+ wprocess.kill();
}
}
} // end protected void doClose
@@ -346,4 +358,14 @@ public class WindowsLocalHost extends LocalHost {
return true;
} // end public boolean mkdirs
+ public static int getWindowsProcessID(Process process) {
+ try {
+ // clean way
+ WinProcess wproc = new WinProcess(process);
+ return wproc.getPid();
+ } catch ( Throwable wt ) {
+ return getWindowsProcessIDReflection(process);
+ }
+ }
+
} // end public class WindowsLocalHost
diff --git a/src/com/mostc/pftt/main/CmpReport.java
b/src/com/mostc/pftt/main/CmpReport.java
new file mode 100644
index 0000000..2202046
--- /dev/null
+++ b/src/com/mostc/pftt/main/CmpReport.java
@@ -0,0 +1,553 @@
+package com.mostc.pftt.main;
+
+import groovy.xml.MarkupBuilder;
+
+import java.awt.Desktop;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.apache.commons.net.ftp.FTP;
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPSClient;
+import org.apache.commons.net.util.TrustManagerUtils;
+import org.columba.ristretto.message.Address;
+import org.columba.ristretto.parser.AddressParser;
+import org.columba.ristretto.parser.ParserException;
+import org.columba.ristretto.smtp.SMTPException;
+import org.columba.ristretto.smtp.SMTPProtocol;
+
+import com.github.mattficken.io.ArrayUtil;
+import com.github.mattficken.io.StringUtil;
+import com.mostc.pftt.host.AHost;
+import com.mostc.pftt.host.LocalHost;
+import com.mostc.pftt.model.core.EPhptTestStatus;
+import com.mostc.pftt.model.core.PhpBuildInfo;
+import com.mostc.pftt.results.AbstractPhpUnitRW;
+import com.mostc.pftt.results.AbstractPhptRW;
+import com.mostc.pftt.results.AbstractTestResultRW;
+import com.mostc.pftt.results.ConsoleManager;
+import com.mostc.pftt.results.LocalConsoleManager;
+import com.mostc.pftt.results.PhpResultPack;
+import com.mostc.pftt.results.PhpResultPackReader;
+import com.mostc.pftt.results.TextBuilder;
+import com.mostc.pftt.util.EMailUtil;
+import com.mostc.pftt.util.EMailUtil.ESMTPAuthMethod;
+import com.mostc.pftt.util.EMailUtil.ESMTPSSL;
+
+public class CmpReport {
+ static String generateFileName(AbstractPhptRW base, AbstractPhptRW
test) {
+ String file_name = "PHPT_CMP_"
+
+base.getBuildInfo().getBuildBranch()+"-"+base.getBuildInfo().getVersionRevision()+"-"+base.getBuildInfo().getBuildType()+"-"+base.getBuildInfo().getCPUArch()+"-"+base.getBuildInfo().getCompiler()+"_"+base.getScenarioSetNameWithVersionInfo()+
+ "_v_"
+
+test.getBuildInfo().getBuildBranch()+"-"+test.getBuildInfo().getVersionRevision()+"-"+test.getBuildInfo().getBuildType()+"-"+test.getBuildInfo().getCPUArch()+"-"+test.getBuildInfo().getCompiler()+"_"+test.getScenarioSetNameWithVersionInfo();
+ file_name = StringUtil.max(file_name, 100);
+
+ return file_name + ".html";
+ }
+ static String generateFileName(AbstractPhpUnitRW base,
AbstractPhpUnitRW test) {
+ String file_name =
"PhpUnit_CMP_"+test.getTestPackNameAndVersionString()+"_"
+
+base.getBuildInfo().getBuildBranch()+"-"+base.getBuildInfo().getVersionRevision()+"-"+base.getBuildInfo().getBuildType()+"-"+base.getBuildInfo().getCPUArch()+"-"+base.getBuildInfo().getCompiler()+"_"+base.getScenarioSetNameWithVersionInfo()+
+ "_v_"
+
+test.getBuildInfo().getBuildBranch()+"-"+test.getBuildInfo().getVersionRevision()+"-"+test.getBuildInfo().getBuildType()+"-"+test.getBuildInfo().getCPUArch()+"-"+test.getBuildInfo().getCompiler()+"_"+test.getScenarioSetNameWithVersionInfo();
+ file_name = StringUtil.max(file_name, 80);
+
+ return file_name + ".html";
+ }
+ static class Verify implements IRecvr {
+
+ @Override
+ public void recv(AbstractPhptRW base, AbstractPhptRW test,
PHPTMultiHostTwoBuildSingleScenarioSetReportGen phpt_report, String html_str)
throws IOException {
+ File html_file = new
File("c:\\php-sdk\\"+generateFileName(base, test));
+ FileWriter fw = new FileWriter(html_file);
+ fw.write(html_str);
+ fw.close();
+
+ Desktop.getDesktop().browse(html_file.toURI());
+ }
+
+ @Override
+ public void recv(AbstractPhpUnitRW base, AbstractPhpUnitRW
test, PhpUnitMultiHostTwoBuildSingleScenarioSetReportGen php_unit_report,
String html_str) throws IOException {
+ File html_file = new
File("c:\\php-sdk\\"+generateFileName(base, test));
+ FileWriter fw = new FileWriter(html_file);
+ fw.write(html_str);
+ fw.close();
+ Desktop.getDesktop().browse(html_file.toURI());
+ }
+
+ @Override
+ public void start(PhpResultPack test_pack) throws Exception {}
+
+ @Override
+ public void stop(PhpResultPack test_pack) throws Exception {}
+
+ }
+ static class Mailer {
+ final Address from, puts_admin;
+ final Address[] puts_users;
+ SMTPProtocol smtp;
+ final boolean debug, force;
+ LinkedList<String> message_bodies = new LinkedList<String>();
+ final String phpt_prefix;
+
+ Mailer(boolean debug, boolean force, Address[] puts_users)
throws ParserException {
+ this("Core", debug, force, puts_users);
+ }
+
+ Mailer(String phpt_prefix, boolean debug, boolean force,
Address[] puts_users) throws ParserException {
+ this.phpt_prefix = phpt_prefix;
+ this.debug = debug;
+ this.force = force;
+ from =
AddressParser.parseAddress("[email protected]");
+ this.puts_users = puts_users;
+ puts_admin =
AddressParser.parseAddress("[email protected]");
+ }
+
+ protected void connect() throws IOException, SMTPException {
+ smtp = EMailUtil.connect("smtp.live.com", 587, from,
ESMTPSSL.IMPLICIT_SSL, ESMTPAuthMethod.PLAIN, "[email protected]",
"php868841432".toCharArray());
+ }
+
+ protected String getSubjectPrefix(Address to) {
+ String ma = to.getMailAddress();
+ int i = ma.indexOf('@');
+ if (i==-1)
+ return "";
+ ma = ma.substring(0, i);
+ ma = ma.trim();
+ if (ma.length()==0)
+ return "";
+ else
+ return "["+ma.toUpperCase()+"] ";
+ }
+ protected void sendMail(boolean too_much_change, String
subject, String html_str) throws IOException, SMTPException, Exception {
+ // prevent sending duplicate messages
+ if (message_bodies.contains(html_str)) {
+ return;
+ }
+ message_bodies.add(html_str);
+ Collection<Address> recipients;
+ if (!force && too_much_change) {
+ System.err.println("Debug: too much change,
sending to admin only");
+ recipients = ArrayUtil.toList(puts_admin);
+ subject = "[PUTS] Review " + subject;
+ } else {
+ // this is probably going to a mailing list
+ // a common convention for mailing lists is for
automated mail to
+ // have a subject prefixed with the mailing
list's name
+ //subject = getSubjectPrefix(report_to)+subject;
+ //
+ // instead, promote the `PUTS` name
+ subject = "[PUTS] "+subject;
+ if (debug)
+ recipients =
ArrayUtil.toList(puts_admin);
+ else
+ recipients =
ArrayUtil.toList(puts_users);
+ }
+ try {
+ EMailUtil.sendHTMLMessage(
+ smtp,
+ from,
+ recipients,
+ subject,
+ html_str
+ );
+ } catch ( Exception ex ) {
+ // errors seen:
+ // 5.3.4 Requested action not taken; We noticed
some unusual activity in your Hotmail account. To help protect you, we've
temporarily blocked your account.
+ // -can't send email to puts_admin in this
case (can't send email)
+ // TODO should log these errors - especially
5.3.4
+ ex.printStackTrace();
+
+ // reconnect and retry once
+ smtp.dropConnection();
+
+ connect();
+
+ EMailUtil.sendHTMLMessage(
+ smtp,
+ from,
+ recipients,
+ subject,
+ html_str
+ );
+ }
+ }
+
+ public String createSubject(PhpBuildInfo info) {
+ return info.getBuildBranch()+"
"+info.getVersionRevision()+"-"+info.getBuildType()+"-"+info.getCPUArch();
+ }
+ }
+ static class Mail extends Mailer implements IRecvr {
+ LinkedList<String> message_bodies = new LinkedList<String>();
+
+ Mail(boolean debug, boolean force, Address[] puts_users) throws
ParserException {
+ super(debug, force, puts_users);
+ }
+
+ Mail(String phpt_prefix, boolean debug, boolean force,
Address[] puts_users) throws ParserException {
+ super(phpt_prefix, debug, force, puts_users);
+ }
+
+ @Override
+ public void recv(AbstractPhptRW base, AbstractPhptRW test,
PHPTMultiHostTwoBuildSingleScenarioSetReportGen phpt_report, String html_str)
throws IOException, SMTPException, Exception {
+ if (test.count(EPhptTestStatus.PASS)<100)
+ return;
+ sendMail(
+ !force && test.isTooMuchChange(base),
+ phpt_prefix+" PHPT Report
"+createSubject(test.getBuildInfo()),
+ html_str
+ );
+ }
+
+ @Override
+ public void recv(AbstractPhpUnitRW base, AbstractPhpUnitRW
test, PhpUnitMultiHostTwoBuildSingleScenarioSetReportGen php_unit_report,
String html_str) throws IOException, SMTPException, Exception {
+ sendMail(
+ !force && test.isTooMuchChange(base),
+ "Application PhpUnit Report
"+createSubject(test.getBuildInfo()),
+ html_str
+ );
+ }
+
+ @Override
+ public void start(PhpResultPack test_pack) throws Exception {
+ connect();
+ }
+
+ @Override
+ public void stop(PhpResultPack test_pack) throws Exception {
+ message_bodies.clear();
+ }
+ }
+ enum EFTPSSL {
+ NO_SSL,
+ REQUIRE_SSL,
+ DETECT_SSL
+ }
+ static class Upload implements IRecvr {
+ static FTPClient configureClient(FTPSClient ftps) {
+
ftps.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());
+ return ftps;
+ }
+
+ FTPClient ftp;
+
+ @Override
+ public void start(PhpResultPack test_pack) throws IOException {
+ connect();
+ }
+
+ protected void connect() throws IOException {
+ EFTPSSL use_ssl = EFTPSSL.NO_SSL;
+ switch(use_ssl) {
+ case REQUIRE_SSL:
+ ftp = configureClient(new FTPSClient(true));
+ break;
+ case DETECT_SSL:
+ ftp = configureClient(new FTPSClient(false));
+ break;
+ default:
+ ftp = new FTPClient();
+ }
+
+ ftp.connect("131.107.220.66", 21); // TODO
+ ftp.login("pftt", "1nter0pLAb!!");
+ ftp.setFileType(FTP.BINARY_FILE_TYPE);
+ }
+
+ static final String[] HOSTS86 = new String[]{"2008r2sp0",
"2008r2sp1", "Win7sp0-x64", "Win7sp1-x64", "Win7sp0-x86", "Win7sp1-x86",
"Vistasp2-x86", "Vistasp2-x64", "2008sp0-x86", "2008sp0-x64", "2008sp1-x86",
"2008sp1-x64", "2012sp0", "8sp0-x64", "2012r2"};
+ static final String[] HOSTS64 = new String[]{"2008r2sp0",
"2008r2sp1", "Win7sp0-x64", "Win7sp1-x64", "Vistasp2-x64", "2008sp0-x64",
"2008sp1-x64", "2012sp0", "8sp0-x64", "2012r2"};
+ @Override
+ public void stop(PhpResultPack test_pack) throws
IllegalStateException, Exception {
+ LocalHost host = LocalHost.getInstance();
+ // copy_hosts
+ {
+ File[] fhosts =
test_pack.getResultPackPath().listFiles();
+ for ( File fhost : fhosts ) {
+ if (fhost.isDirectory()) {
+ //
+ final String prefix =
Character.toString((char)( 74 + new java.util.Random().nextInt(3)));
+ final String[] hosts =
test_pack.getBuildInfo().isX64() ? HOSTS64 : HOSTS86;
+
+ for ( int i=0 ; i <
hosts.length ; i++ ) {
+ final String hostname =
prefix + "-" +hosts[i];
+
+ final File target_file
= new File(fhost.getParentFile(), hostname);
+
System.out.println(fhost+" "+target_file+" "+i);
+ if (i==0) {
+
host.move(fhost.getAbsolutePath(), target_file.getAbsolutePath());
+ fhost =
target_file;
+ } else {
+
host.copy(fhost.getAbsolutePath(), target_file.getAbsolutePath());
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ final String temp_file = host.mktempname("Uploader",
".7z");
+
+ System.out.println("Compressing result-pack:
"+test_pack.getResultPackPath());
+
+ host.compress(null, host,
test_pack.getResultPackPath().getAbsolutePath(), temp_file);
+
+ final String remote_file =
generateFolder(test_pack)+"/"+test_pack.getResultPackPath().getName()+".7z";
+
+ System.out.println("Compressed. Uploading "+temp_file+"
to "+remote_file);
+
+ retryStore(generateFolder(test_pack), remote_file, new
BufferedInputStream(new FileInputStream(temp_file)));
+
+ System.out.println("Uploaded result-pack
"+test_pack.getResultPackPath()+" to "+remote_file);
+
+ ftp.logout();
+ ftp.disconnect();
+
+ host.delete(temp_file);
+ }
+
+ protected void retryStore(String folder, String file,
InputStream in) throws IOException {
+ for ( int i=0 ; i < 10 ; i++ ) {
+ try {
+ ftp.mkd(folder);
+ ftp.storeFile(file, in);
+ break;
+ } catch ( Exception ex ) {
+ ex.printStackTrace();
+ // these methods can block forever if
there was an exception
+ //ftp.logout();
+ //ftp.disconnect();
+ // this too? ftp.quit();
+ ftp = null;
+ connect();
+ }
+ }
+ }
+
+ static String generateFolder(PhpResultPack test_pack) {
+ return
"/PFTT-Results/"+test_pack.getBuildInfo().getBuildBranch()+"/"+test_pack.getBuildInfo().getVersionRevision();
+ }
+ static String generateFolder(AbstractTestResultRW test) {
+ return
"/PFTT-Results/"+test.getBuildInfo().getBuildBranch()+"/"+test.getBuildInfo().getVersionRevision();
+ }
+
+ @Override
+ public void recv(AbstractPhptRW base, AbstractPhptRW test,
PHPTMultiHostTwoBuildSingleScenarioSetReportGen phpt_report, String html_str)
throws IOException {
+ final String folder = generateFolder(test);
+
+ final String file = generateFileName(base, test);
+
+ retryStore(folder, folder+"/"+file, new
ByteArrayInputStream(html_str.getBytes()));
+ }
+
+ @Override
+ public void recv(AbstractPhpUnitRW base, AbstractPhpUnitRW
test, PhpUnitMultiHostTwoBuildSingleScenarioSetReportGen php_unit_report,
String html_str) throws IOException {
+ final String folder = generateFolder(test);
+
+ final String file = generateFileName(base, test);
+
+ retryStore(folder, folder+"/"+file, new
ByteArrayInputStream(html_str.getBytes()));
+ }
+
+ }
+ interface IRecvr {
+ void recv(AbstractPhptRW base, AbstractPhptRW test,
PHPTMultiHostTwoBuildSingleScenarioSetReportGen phpt_report, String html_str)
throws IOException, SMTPException, Exception;
+ void recv(AbstractPhpUnitRW base, AbstractPhpUnitRW test,
PhpUnitMultiHostTwoBuildSingleScenarioSetReportGen php_unit_report, String
html_str) throws IOException, SMTPException, Exception;
+ void start(PhpResultPack test_pack) throws Exception;
+ void stop(PhpResultPack test_pack) throws Exception;
+ }
+ static void clean_hosts(AHost host, File pack) throws
IllegalStateException, IOException {
+ File[] hosts = pack.listFiles();
+ boolean is_first = true;
+ for ( File fhost : hosts ) {
+ if ( fhost.isDirectory() ) {
+ if (is_first) {
+ // don't delete all, leave first folder
found
+ is_first = false;
+ } else {
+ System.err.println("delete "+fhost);
+ host.delete(fhost.getAbsolutePath());
+ }
+ }
+ }
+ }
+ public static void main(String[] args) throws Exception {
+ //IRecvr recvr = new Verify();
+ //
+ // mssql uses a different test-pack so reports only for that
test-pack can be mailed
+ // whereas wincacheu is a bunch of scenarios for both core and
mssql test-packs
+ // therefore all reports must go to wincache
+ // -shows how wincacheu scenarios compare to other
scenarios
+ // -shows the mssql driver with wincacheu
+ final Mailer summary_mailer = new Mailer(false, false, new
Address[]{AddressParser.parseAddress("[email protected]")});
+ final IRecvr CORE_PRODUCTION_SNAP = new Mail(false, false, new
Address[]{AddressParser.parseAddress("[email protected]"),
AddressParser.parseAddress("[email protected]")});
+ //final IRecvr CORE_PRODUCTION_SNAP = new Mail(false, false,
new Address[]{AddressParser.parseAddress("[email protected]")});
+ // TODO final IRecvr MSSQL_PRODUCTION_SNAP = new Mail("MSSQL",
false, false,
AddressParser.parseAddress("[email protected];[email protected];[email protected]"),AddressParser.parseAddress("[email protected]"));
+ final IRecvr MSSQL_PRODUCTION_SNAP = new Mail("MSSQL", false,
true, new Address[]{AddressParser.parseAddress("[email protected]"),
AddressParser.parseAddress("[email protected]")});
+ // TODO final IRecvr CORE_PRODUCTION_RELEASE = new Mail(false,
true,
AddressParser.parseAddress("[email protected];[email protected];[email protected]"));
+ final IRecvr CORE_PRODUCTION_RELEASE = new Mail(false, true,
new Address[]{AddressParser.parseAddress("[email protected]")});
+ final IRecvr CORE_PRODUCTION_QA = new Mail(false, true, new
Address[]{AddressParser.parseAddress("[email protected]")});
+ final IRecvr TEST = new Mail(true, false, new
Address[]{AddressParser.parseAddress("[email protected]")});
+ //IRecvr recvr = CORE_PRODUCTION_SNAP; // TODO
+ //IRecvr recvr = CORE_PRODUCTION_RELEASE;
+ //IRecvr recvr = MSSQL_PRODUCTION_SNAP;
+ IRecvr recvr = new Upload();
+
+ LocalHost host = LocalHost.getInstance();
+ LocalConsoleManager cm = new LocalConsoleManager();
+
+ // TODO check if a smoke test failed!
+ //File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-5.3.27rc1-nTS-X86-VC9"));
+ //File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-5.3.27-nTS-X86-VC9"));
+ //File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-re2e002d-nTS-X86-VC9"));
+ //File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-r7c9bb87-nTS-X86-VC9"));
+ //File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-re2e002d-TS-X86-VC9"));
+ //File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_3-Result-Pack-r7c9bb87-TS-X86-VC9"));
+ //File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-5.4.20rc1-TS-X86-VC9"));
+ //File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-5.4.20-TS-X86-VC9"));
+
+ //File base_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-rd487f5e-TS-X86-VC9");
+ //File test_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-r6c48c6b-TS-X86-VC9");
+ //File base_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-ra03f094-nTS-X86-VC9");
+ //File test_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-r72aacbf-nTS-X86-VC9");
+
+ //File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-rc8b0da6-TS-X64-VC11"));
+ //File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-rc8b0da6-TS-x64-VC11"));
+ //File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-r82dd6b9-NTS-X64-VC11"));
+ //File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-rc8b0da6-NTS-X64-VC11"));
+ //File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-rb2ee1b6-NTS-X86-VC11"));
+ //File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-rfc9d886-NTS-X86-VC11"));
+ //File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-rc8b0da6-TS-X86-VC11"));
+ //File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-rfc9d886-TS-X86-VC11"));
+
+ //File base_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_Master-Result-Pack--TS-X86-VC11");
+ //File base_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_Master-Result-Pack-r43289d6-TS-X86-VC11");
+ //File test_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_6-Result-Pack-5.6.0-dev-TS-X86-VC11-keyword916");
+ //File base_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_Master-Result-Pack-r89c4aba-NTS-X64-VC11");
+ //File base_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_Master-Result-Pack-r82bb2a2-NTS-X86-VC11");
+ //File test_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_6-Result-Pack-5.6.0-dev-NTS-X86-VC11-keyword916");
+ //File base_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_Master-Result-Pack-r5e1ac55-NTS-X86-VC11");
+ //File test_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_Master-Result-Pack-r82bb2a2-NTS-X86-VC11");
+ //File base_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_Master-Result-Pack-rd515455-TS-X64-VC11");
+ //File test_dir = new
File("C:\\php-sdk\\PFTT-Auto\\PHP_Master-Result-Pack-r04fcf6a-TS-X64-VC11");
+
+ File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-5.5.6RC1-TS-X64-VC11"));
+ File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_5-Result-Pack-5.5.6-TS-X64-VC11"));
+ //File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-5.4.22rc1-NTS-X86-VC9-SQLSVR"));
+ //File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-5.4.22-NTS-X86-VC9-SQLSVR"));
+ //File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-5.4.22rc1-TS-X86-VC9"));
+ //File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_4-Result-Pack-5.4.22-TS-X86-VC9"));
+ //File base_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_Master-Result-Pack-ra0244a6-NTS-X86-VC11"));
+ //File test_dir = (new
File("C:\\php-sdk\\PFTT-Auto\\PHP_5_6-Result-Pack-5.6.0-50333-NTS-X86-VC11"));
+
+
+ // clean_hosts
+ clean_hosts(host, base_dir);
+ clean_hosts(host, test_dir);
+ PhpResultPackReader base_pack = PhpResultPackReader.open(cm,
host, base_dir);
+ PhpResultPackReader test_pack = PhpResultPackReader.open(cm,
host, test_dir);
+
+ // TODO temp
+ //report("Core", cm, recvr, base_pack, test_pack);
+ summary(summary_mailer, cm, base_pack, test_pack);
+
+ }
+ static void summary(Mailer m, ConsoleManager cm, PhpResultPackReader
base_pack, PhpResultPackReader test_pack) throws IOException, SMTPException,
Exception {
+ CmpReport2 cmp = new CmpReport2();
+ cmp.add(base_pack);
+ cmp.add(test_pack);
+
+ AHost host = LocalHost.getInstance();
+
+ {
+ StringWriter sw = new StringWriter();
+ TextBuilder text = new TextBuilder(sw);
+
+ new CmpReport2G().run(text, cmp, cm);
+ //m.connect();
+ //m.sendMail(false, "Summary
"+m.createSubject(test_pack.getBuildInfo()), sw.toString());
+ host.saveTextFile("c:\\php-sdk\\test.txt",
sw.toString());
+ host.exec("notepad c:\\php-sdk\\test.txt",
AHost.FOUR_HOURS);
+ }
+ {
+ StringWriter sw = new StringWriter();
+ MarkupBuilder html = new MarkupBuilder(sw);
+
+ new CmpReport2G().run(html, cmp, cm);
+ //m.connect();
+ //m.sendMail(false, "Summary
"+m.createSubject(test_pack.getBuildInfo()), sw.toString());
+ host.saveTextFile("c:\\php-sdk\\test.html",
sw.toString());
+ host.exec("start c:\\php-sdk\\test.html",
AHost.FOUR_HOURS);
+ }
+ }
+ static void report(String phpt_prefix, ConsoleManager cm, IRecvr recvr,
PhpResultPack base_pack, PhpResultPack test_pack) throws IOException,
SMTPException, Exception {
+ recvr.start(test_pack);
+
+ // TODO turn off phpt or phpunit reports or turn off all but a
specific test-pack
+ for ( AbstractPhpUnitRW base : base_pack.getPhpUnit() ) {
+ for ( AbstractPhpUnitRW test : test_pack.getPhpUnit() )
{
+ System.out.println("PhpUnit
"+base.getScenarioSetNameWithVersionInfo()+"
"+test.getScenarioSetNameWithVersionInfo());
+ //if
(!base.getTestPackNameAndVersionString().contains("Wordpress"))
+ //continue;
+ if (!eq(base.getTestPackNameAndVersionString(),
test.getTestPackNameAndVersionString()))
+ continue;
+ // TODO mysql
+ if
(!base.getScenarioSetNameWithVersionInfo().replace("MySQL-5.6_",
"").replace("7.0.1",
"7.0.2").equals(test.getScenarioSetNameWithVersionInfo().replace("MySQL-5.6_",
"")))
+ /*
+
!(base.getScenarioSetNameWithVersionInfo().toLowerCase().contains("opcache")==test.getScenarioSetNameWithVersionInfo().toLowerCase().contains("opcache")
+ &&(
+
test.getScenarioSetNameWithVersionInfo().toLowerCase().contains("cli")||
+
test.getScenarioSetNameWithVersionInfo().toLowerCase().contains("builtin")||
+
test.getScenarioSetNameWithVersionInfo().toLowerCase().contains("apache")
+ )
+
&&base.getScenarioSetNameWithVersionInfo().toLowerCase().contains("cli")==test.getScenarioSetNameWithVersionInfo().toLowerCase().contains("cli")
+
&&base.getScenarioSetNameWithVersionInfo().toLowerCase().contains("builtin")==test.getScenarioSetNameWithVersionInfo().toLowerCase().contains("builtin")
+
&&base.getScenarioSetNameWithVersionInfo().toLowerCase().contains("apache")==test.getScenarioSetNameWithVersionInfo().toLowerCase().contains("apache")
+
&&base.getScenarioSetNameWithVersionInfo().toLowerCase().contains("local")==test.getScenarioSetNameWithVersionInfo().toLowerCase().contains("local")
+
&&base.getScenarioSetNameWithVersionInfo().toLowerCase().contains("smb-dfs")==test.getScenarioSetNameWithVersionInfo().toLowerCase().contains("smb-dfs")
+
&&base.getScenarioSetNameWithVersionInfo().toLowerCase().contains("smb-dedup")==test.getScenarioSetNameWithVersionInfo().toLowerCase().contains("smb-dedup")
+
&&base.getScenarioSetNameWithVersionInfo().toLowerCase().contains("smb-basic")==test.getScenarioSetNameWithVersionInfo().toLowerCase().contains("smb-basic")
+ ))*/
+ continue;
+
+
PhpUnitMultiHostTwoBuildSingleScenarioSetReportGen php_unit_report = new
PhpUnitMultiHostTwoBuildSingleScenarioSetReportGen(base, test);
+
+ String html_str =
php_unit_report.getHTMLString(cm, !(recvr instanceof Upload));
+
+ recvr.recv(base, test, php_unit_report,
html_str);
+
+ }
+ }
+ //System.exit(0);
+ for ( AbstractPhptRW base : base_pack.getPHPT() ) {
+ for ( AbstractPhptRW test : test_pack.getPHPT() ) {
+ System.out.println("PHPT
"+base.getScenarioSetNameWithVersionInfo()+"
"+test.getScenarioSetNameWithVersionInfo()+" "+base+" "+test);
+ if
(!eq(base.getScenarioSetNameWithVersionInfo(),
test.getScenarioSetNameWithVersionInfo()))
+ continue;
+
+ PHPTMultiHostTwoBuildSingleScenarioSetReportGen
phpt_report = new PHPTMultiHostTwoBuildSingleScenarioSetReportGen(phpt_prefix,
base, test);
+ String html_str = phpt_report.getHTMLString(cm,
!(recvr instanceof Upload));
+
+ recvr.recv(base, test, phpt_report, html_str);
+ }
+ }
+ recvr.stop(test_pack);
+ }
+ static boolean eq(String base, String test) {
+ if (base==null||test==null)
+ return false;
+ base = base.replace("MySQL-5.6_", "");
+ base = base.replace("7.0.1", "7.0.2");
+ base = base.replace("-1.3.4", "");
+ test = test.replace("7.0.1", "7.0.2");
+ test = test.replace("MySQL-5.6_", "");
+ test = test.replace("-1.3.4", "");
+ return base.startsWith(test)||test.startsWith(base);
+ }
+}
diff --git a/src/com/mostc/pftt/main/CmpReport2.java
b/src/com/mostc/pftt/main/CmpReport2.java
new file mode 100644
index 0000000..ed43f62
--- /dev/null
+++ b/src/com/mostc/pftt/main/CmpReport2.java
@@ -0,0 +1,306 @@
+package com.mostc.pftt.main;
+
+import groovy.lang.GroovyObject;
+import groovy.xml.MarkupBuilder;
+
+import java.awt.Desktop;
+import java.io.File;
+import java.io.FileWriter;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.github.mattficken.io.ArrayUtil;
+import com.mostc.pftt.host.AHost;
+import com.mostc.pftt.host.LocalHost;
+import com.mostc.pftt.model.app.EPhpUnitTestStatus;
+import com.mostc.pftt.model.core.EPhptTestStatus;
+import com.mostc.pftt.model.core.PhpBuildInfo;
+import com.mostc.pftt.results.AbstractPhpUnitRW;
+import com.mostc.pftt.results.AbstractPhptRW;
+import com.mostc.pftt.results.LocalConsoleManager;
+import com.mostc.pftt.results.PhpResultPackReader;
+import com.mostc.pftt.scenario.ScenarioSet;
+
+public class CmpReport2 {
+ final HashMap<PhpBuildInfo,PhpResultPackReader> result_packs;
+ final LinkedList<String> phpt_test_packs, phpunit_test_packs;
+ final LinkedList<AHost> hosts;
+ final HashMap<String,LinkedList<ScenarioSet>> phpt_scenario_sets,
phpunit_scenario_sets;
+
+ public CmpReport2() {
+ result_packs = new HashMap<PhpBuildInfo,PhpResultPackReader>();
+ phpt_test_packs = new LinkedList<String>();
+ phpunit_test_packs = new LinkedList<String>();
+ phpt_scenario_sets = new
HashMap<String,LinkedList<ScenarioSet>>();
+ phpunit_scenario_sets = new
HashMap<String,LinkedList<ScenarioSet>>();
+ hosts = new LinkedList<AHost>();
+ }
+
+ void add(PhpResultPackReader result_pack) {
+ PhpBuildInfo build_info = result_pack.getBuildInfo();
+ if (result_packs.containsKey(build_info))
+ return;
+ result_packs.put(build_info, result_pack);
+ for ( AHost host : result_pack.getHosts() ) {
+ if (!hosts.contains(host))
+ hosts.add(host);
+ for ( String phpt_test_pack :
result_pack.getPhptTestPacks(host)) {
+ // TODO temp if
(!phpt_test_packs.contains(phpt_test_pack))
+ phpt_test_packs.add(phpt_test_pack);
+ LinkedList<ScenarioSet> sets =
phpt_scenario_sets.get(phpt_test_pack);
+ if (sets==null) {
+ sets = new LinkedList<ScenarioSet>();
+ phpt_scenario_sets.put(phpt_test_pack,
sets);
+ }
+ for ( ScenarioSet scenario_set :
result_pack.getPhptScenarioSets(host, phpt_test_pack) ) {
+ boolean a = true;
+ for ( ScenarioSet other : sets ) {
+ if
(other.toString().equals(scenario_set.toString())) {
+ a = false;
+ break;
+ }
+ }
+ if (a)
+ sets.add(scenario_set);
+ }
+ }
+ for ( String phpunit_test_pack :
result_pack.getPhpUnitTestPacks(host)) {
+ if
(!phpunit_test_packs.contains(phpunit_test_pack))
+
phpunit_test_packs.add(phpunit_test_pack);
+ LinkedList<ScenarioSet> sets =
phpunit_scenario_sets.get(phpunit_test_pack);
+ if (sets==null) {
+ sets = new LinkedList<ScenarioSet>();
+
phpunit_scenario_sets.put(phpunit_test_pack, sets);
+ }
+ for ( ScenarioSet scenario_set :
result_pack.getPhpUnitScenarioSets(host, phpunit_test_pack) ) {
+ boolean a = true;
+ for ( ScenarioSet other : sets ) {
+ if
(other.toString().equals(scenario_set.toString())) {
+ a = false;
+ break;
+ }
+ }
+ if (a)
+ sets.add(scenario_set);
+ }
+ }
+ }
+ System.out.println("67 "+phpunit_scenario_sets);
+ System.out.println(phpt_test_packs);
+ System.out.println(phpunit_test_packs);
+ }
+
+ final HashMap<String,String> color_map = new HashMap<String,String>();
+ String getColor(String scenario_set_str) {
+ String color = color_map.get(scenario_set_str);
+ if (color!=null)
+ return color;
+ Collection<String> colors = color_map.values();
+ switch(colors.size()%20) {
+ case 0:
+ color = "#ff1b1b";
+ break;
+ case 1:
+ color = "#1bff1b";
+ break;
+ case 2:
+ color = "#1bcece";
+ break;
+ case 3:
+ color = "#ffce1b";
+ break;
+ case 4:
+ color = "#aaff1b";
+ break;
+ case 5:
+ color = "#1baaff";
+ break;
+ case 6:
+ color = "#ff1baa";
+ break;
+ case 7:
+ color = "#eaea1b";
+ break;
+ case 8:
+ color = "#ea1bff";
+ break;
+ case 9:
+ color = "#ff1bea";
+ break;
+ case 10:
+ color = "#1beaff";
+ break;
+ case 11:
+ color = "#86ff1b";
+ break;
+ case 12:
+ color = "#ff1b86";
+ break;
+ case 13:
+ color = "#1b86ff";
+ break;
+ case 14:
+ color = "#861bff";
+ break;
+ case 15:
+ color = "#01ff1b";
+ break;
+ case 16:
+ color = "#ff011b";
+ break;
+ case 17:
+ color = "#ff1b01";
+ break;
+ case 18:
+ color = "#00aaff";
+ break;
+ case 19:
+ color = "#aa00ff";
+ break;
+ }
+ color_map.put(scenario_set_str, color);
+ return color;
+ }
+
+ PhpResultPackReader get(PhpBuildInfo build_info) {
+ return result_packs.get(build_info);
+ }
+ AbstractPhptRW getPhpt(AHost host, PhpBuildInfo build_info, ScenarioSet
scenario_set, String test_pack_name) {
+ try {
+ return get(build_info).getPHPT(host, scenario_set,
test_pack_name);
+ } catch ( Exception ex ) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+ AbstractPhpUnitRW getPhpUnit(AHost host, PhpBuildInfo build_info,
ScenarioSet scenario_set, String test_pack_name_and_version) {
+ try {
+ return get(build_info).getPhpUnit(host,
test_pack_name_and_version, scenario_set);
+ } catch ( Exception ex ) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+ List<ScenarioSet> getPhptScenarioSets(String
test_pack_name_and_version) {
+ return phpt_scenario_sets.get(test_pack_name_and_version);
+ }
+ List<ScenarioSet> getPhpUnitScenarioSets(String
test_pack_name_and_version) {
+ return phpunit_scenario_sets.get(test_pack_name_and_version);
+ }
+ List<String> getUniquePhptTestNames(PhpBuildInfo build_info, String
test_pack_name_and_version, ScenarioSet scenario_set, EPhptTestStatus status) {
+ LinkedList<String> out = new LinkedList<String>();
+ for ( AHost host : hosts ) {
+ for ( PhpResultPackReader result_pack :
result_packs.values()) {
+ for ( AbstractPhptRW r :
result_pack.getPHPT(host) ) {
+ if
(!r.getScenarioSetNameWithVersionInfo().equals(scenario_set.toString()))
+ continue;
+ if
(!r.getTestPackVersion().equals(test_pack_name_and_version))
+ continue;
+ List<String> n = r.getTestNames(status);
+ for ( String a : n )
+ out.remove(a);
+ }
+ }
+ }
+ Collections.sort(out);
+ return out;
+ }
+ List<String> getPhptTestNames(String test_pack_name_and_version,
EPhptTestStatus status) {
+ LinkedList<String> out = new LinkedList<String>();
+ for ( PhpResultPackReader result_pack : result_packs.values()) {
+ for ( AHost host : hosts ) {
+ for ( AbstractPhptRW r :
result_pack.getPHPT(host, test_pack_name_and_version) )
+
ArrayUtil.copyNoDuplicates(r.getTestNames(status), out);
+ }
+ }
+ Collections.sort(out);
+ return out;
+ }
+ List<String> getPhptScenarioSets(PhpBuildInfo build_info, String
test_pack_name_and_version, String test_name, EPhptTestStatus status) {
+ LinkedList<String> out = new LinkedList<String>();
+ String scenario_set_str;
+ for ( AHost host : hosts ) {
+ for ( AbstractPhptRW r : get(build_info).getPHPT(host,
test_pack_name_and_version) ) {
+ if (r.isTestStatus(test_name, status)) {
+ scenario_set_str =
r.getScenarioSetNameWithVersionInfo();
+ if (!out.contains(scenario_set_str))
+ out.add(scenario_set_str);
+ }
+ }
+ }
+ return out;
+ }
+ List<String> getUniquePhpUnitTestNames(PhpBuildInfo build_info, String
test_pack_name_and_version, ScenarioSet scenario_set, EPhpUnitTestStatus
status) {
+ LinkedList<String> out = new LinkedList<String>();
+
+ for ( AHost host : hosts ) {
+ for ( PhpResultPackReader result_pack :
result_packs.values()) {
+ for ( AbstractPhpUnitRW r :
result_pack.getPhpUnit(host) ) {
+ if
(!r.getScenarioSetNameWithVersionInfo().equals(scenario_set.toString()))
+ continue;
+ if
(!r.getTestPackNameAndVersionString().equals(test_pack_name_and_version))
+ continue;
+ List<String> n = r.getTestNames(status);
+ ArrayUtil.copyNoDuplicates(n, out);
+ }
+ }
+ }
+ Collections.sort(out);
+ return out;
+ }
+ List<String> getPhpUnitTestNames(String test_pack_name_and_version,
EPhpUnitTestStatus status) {
+ LinkedList<String> out = new LinkedList<String>();
+ for ( PhpResultPackReader result_pack : result_packs.values()) {
+ for ( AHost host : hosts ) {
+ for ( AbstractPhpUnitRW r :
result_pack.getPhpUnit(host, test_pack_name_and_version) ) {
+
ArrayUtil.copyNoDuplicates(r.getTestNames(status), out);
+ }
+ }
+ }
+ Collections.sort(out);
+ return out;
+ }
+ List<String> getPhpUnitScenarioSets(PhpBuildInfo build_info, String
test_pack_name_and_version, String test_name, EPhpUnitTestStatus status) {
+ LinkedList<String> out = new LinkedList<String>();
+ String scenario_set_str;
+ for ( AHost host : hosts ) {
+ for ( AbstractPhpUnitRW r :
get(build_info).getPhpUnit(host, test_pack_name_and_version) ) {
+ if (r.isTestStatus(test_name, status)) {
+ scenario_set_str =
r.getScenarioSetNameWithVersionInfo();
+ if (!out.contains(scenario_set_str))
+ out.add(scenario_set_str);
+ }
+ }
+ }
+ return out;
+ }
+ public static void main(String[] args) throws Exception {
+ LocalConsoleManager cm = new LocalConsoleManager();
+ CmpReport2 cmp = new CmpReport2();
+ LocalHost localhost = LocalHost.getInstance();
+ //
+ /*cmp.add(PhpResultPackReader.open(cm, localhost, new
File("C:\\php-sdk\\WinCacheU\\PHP_5_5-Result-Pack-5.5.2RC1-NTS-X86-VC11-2")));
+ cmp.add(PhpResultPackReader.open(cm, localhost, new
File("C:\\php-sdk\\WinCacheU\\PHP_5_5-Result-Pack-5.5.3-NTS-X86-VC11")));
+ cmp.add(PhpResultPackReader.open(cm, localhost, new
File("C:\\php-sdk\\WinCacheU\\PHP_5_4-Result-Pack-5.4.18RC2-NTS-X86-VC9-2")));*/
+
+ cmp.add(PhpResultPackReader.open(cm, localhost, new
File("C:\\php-sdk\\PHP_5_5-Result-Pack-5.5.3-NTS-X86-VC11")));
+ cmp.add(PhpResultPackReader.open(cm, localhost, new
File("C:\\php-sdk\\PHP_5_5-Result-Pack-5.5.3-TS-X86-VC11")));
+ cmp.add(PhpResultPackReader.open(cm, localhost, new
File("C:\\php-sdk\\PHP_5_4-Result-Pack-5.4.19-NTS-X86-VC9")));
+ cmp.add(PhpResultPackReader.open(cm, localhost, new
File("C:\\php-sdk\\PHP_5_4-Result-Pack-5.4.19-TS-X86-VC9")));
+ cmp.add(PhpResultPackReader.open(cm, localhost, new
File("C:\\php-sdk\\PHP_5_3-Result-Pack-5.3.27-NTS-X86-VC9")));
+ cmp.add(PhpResultPackReader.open(cm, localhost, new
File("C:\\php-sdk\\PHP_5_3-Result-Pack-5.3.27-TS-X86-VC9")));
+
+ File html_file = new File("c:\\php-sdk\\temp.html");
+ FileWriter fw = new FileWriter(html_file);
+ MarkupBuilder html = new MarkupBuilder(fw);
+
+ new CmpReport2G().run(html, cmp, cm);
+
+ fw.close();
+
+ Desktop.getDesktop().browse(html_file.toURI());
+ }
+}
diff --git a/src/com/mostc/pftt/main/CmpReport2G.groovy
b/src/com/mostc/pftt/main/CmpReport2G.groovy
new file mode 100644
index 0000000..06537ab
--- /dev/null
+++ b/src/com/mostc/pftt/main/CmpReport2G.groovy
@@ -0,0 +1,32 @@
+package com.mostc.pftt.main
+
+import groovy.lang.GroovyObject;
+import groovy.xml.MarkupBuilder;
+
+import com.mostc.pftt.results.ConsoleManager;
+import com.mostc.pftt.host.AHost;
+
+class CmpReport2G {
+ public void run(BuilderSupport html, CmpReport2 cmp, ConsoleManager cm)
{
+ html.html {
+ html.body {
+
+ for (AHost host : cmp.hosts) {
+ // TODO detect multiple hosts and make separate reports
for each host
+ for (String test_pack_name : cmp.phpt_test_packs) {
+
PHPTSingleHostMultiBuildMultiScenarioSetReportGen phpt_report = new
PHPTSingleHostMultiBuildMultiScenarioSetReportGen();
+ phpt_report.run(host, test_pack_name, html,
cmp, cmp.result_packs.keySet(), cm, false);
+ html.br();
+ }
+
+ for (String test_pack_name : cmp.phpunit_test_packs) {
+
PhpUnitSingleHostMultiBuildMultiScenarioSetReportGen phpunit_report = new
PhpUnitSingleHostMultiBuildMultiScenarioSetReportGen();
+ phpunit_report.run(host, test_pack_name, html,
cmp, cmp.result_packs.keySet(), cm, false);
+ html.br()
+ }
+ }
+ } // body
+ } // html
+
+ }
+}
diff --git a/src/com/mostc/pftt/main/PBCReportGen.groovy
b/src/com/mostc/pftt/main/PBCReportGen.groovy
new file mode 100644
index 0000000..561cf97
--- /dev/null
+++ b/src/com/mostc/pftt/main/PBCReportGen.groovy
@@ -0,0 +1,231 @@
+package com.mostc.pftt.main
+/*
+#%powershell1.0%
+#
+# File: results-template.ps1
+# Description: Output $data into html table. This script is meant to be
called from summarize-results.ps1.
+#
+
+Function gaincalc ( $a=0, $b=0 ) {
+ if ( ($a -ne 0) -and ($b -ne 0) ) {
+ $c = ($a / $b) - 1
+
+ switch ($c*100) {
+ {$_ -ge 0 -and $_ -le 3} {$script:gainclass="none"}
+ {$_ -gt 3 -and $_ -le 7}
{$script:gainclass="gainpossmall"}
+ {$_ -ge 0 -and $_ -gt 7} {$script:gainclass="gainpos"}
+ {$_ -lt 0 -and $_ -ge -3} {$script:gainclass="none"}
+ {$_ -lt -3 -and $_ -ge -7}
{$script:gainclass="gainnegsmall"}
+ {$_ -lt 0 -and $_ -lt -7} {$script:gainclass="gainneg"}
+ Default { $script:gainclass="none" }
+ }
+
+ "{0:P2}" -f $c
+ }
+ else {
+ $script:gainclass="none"
+ }
+}
+
+
+write-output "
+
+<html>
+<head>
+ <style type=text/css>
+ .data td { border:1px solid black; }
+ .iis { background-color:#E6B8B7; }
+ .iiswincache { background-color: #DA9694; }
+ .apache { background-color: #C5D9F1; }
+ .apachenoigbinary { background-color: #8DB4E2; }
+ .apachewithigbinary { background-color: #538DD5; }
+ .gainpos { background-color: #00A84C; }
+ .gainpossmall { background-color: #00D661; }
+ .gainneg { background-color: #FF2929; }
+ .gainnegsmall { background-color: #DA9694; }
+ </style>
+ </head>
+
+<body>
+<table border=0 cellpadding=0 cellspacing=0 width=600>
+<tr>
+<td> <strong> PHP Performance </strong> </td>
+<td> <strong> Hardware & Environment </strong> </td>
+</tr><tr>
+<td>$PHP1 - $PHP2</td>
+<td>Dell R710</td>
+</tr><tr>
+<td> </td>
+<td>CPU - Intel Quad core @ 2.26Ghz (x2) L5520</td>
+</tr><tr>
+<td> </td>
+<td>Memory - 12GB RAM</td>
+</tr><tr>
+<td> </td>
+<td>HD - 147GB SAS RAID 1</td>
+</tr><tr>
+<td> </td>
+<td>NIC - 1Gbps Intel</td>
+</tr><tr>
+<td> </td>
+<td>Windows 2008 R2 - SP1</td>
+</tr><tr>
+<td> </td>
+<td>php-web01.ctac.nttest.microsoft.com</td>
+</tr>
+<table>
+<p> </p>
+
+<table border=0 cellpadding=0 cellspacing=0 width=1628 class=data>
+
+<!-- Header Labels -->
+ <tr>
+ <td colspan=4></td>
+ <td colspan=6 class=iis>IIS 7.5</td>
+ <td colspan=9 class=apache>Apache 2.2</td>
+ </tr>
+
+ <tr>
+ <td colspan=4></td>
+ <td colspan=3 rowspan=2 class=iis>No Cache</td>
+ <td colspan=3 rowspan=2 class=iiswincache>WinCache</td>
+ <td colspan=3 rowspan=2 class=apache>No Cache</td>
+ <td colspan=6 class=apachenoigbinary>APC</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td colspan=3>Load Agents</td>
+ <td colspan=3 class=apachenoigbinary>-igbinary</td>
+ <td colspan=3 class=apachewithigbinary>+igbinary</td>
+ </tr>
+ <!-- Header Labels -->
+
+ <tr>
+ <td>Application</td>
+ <td>Physical</td>
+ <td>Virtual</td>
+ <td></td>
+
+<!-- IIS No Cache -->
+
+ <td>$PHP1</td>
+ <td>$PHP2</td>
+ <td>gain</td>
+
+<!-- IIS Cache -->
+ <td>$PHP1</td>
+ <td>$PHP2</td>
+ <td>gain</td>
+
+<!-- Apache No Cache -->
+ <td>$PHP1</td>
+ <td>$PHP2</td>
+ <td>gain</td>
+
+<!-- Apache Cache -igbinary -->
+ <td>$PHP1</td>
+ <td>$PHP2</td>
+ <td>gain</td>
+
+<!-- Apache Cache +igbinary -->
+ <td>$PHP1</td>
+ <td>$PHP2</td>
+ <td>gain</td>
+ </tr>
+
+<!-- Results -->
+"
+
+Foreach ( $app in $appnames ) {
+ ## Notes:
$data[App_Name][Apache|IIS][cache|nocache|cachenoigbinary|cachewithigbinary][php1|php2][ver|tps8|tps16|tps32]
+
+ write-output "
+ <tr>
+ <td rowspan=3>$app</td>
+ "
+
+ Foreach ( $virt in $VIRTUAL ) {
+ $gain = ""
+ $gainclass = ""
+ if ( $virt -ne "8" ) {
+ write-output "<tr>"
+ }
+
+ write-output "
+ <td>2</td>
+ <td>$virt</td>
+ <td> </td>
+
+ <!-- IIS - No Cache -->
+ <td class=iis>" $data[$app]["IIS"]["nocache"]["php1"]["tps$virt"] "</td>
+ <td class=iis>" $data[$app]["IIS"]["nocache"]["php2"]["tps$virt"] "</td>"
+
+ $gain = gaincalc
$data[$app]["IIS"]["nocache"]["php2"]["tps$virt"]
$data[$app]["IIS"]["nocache"]["php1"]["tps$virt"]
+ write-output "
+
+ <td class=$gainclass> $gain
+ </td> <!-- Gain -->
+
+ <!-- IIS - Cache -->
+ <td class=iiswincache>" $data[$app]["IIS"]["cache"]["php1"]["tps$virt"]
"</td>
+ <td class=iiswincache>" $data[$app]["IIS"]["cache"]["php2"]["tps$virt"]
"</td>"
+
+
+ $gain = gaincalc
$data[$app]["IIS"]["cache"]["php2"]["tps$virt"]
$data[$app]["IIS"]["cache"]["php1"]["tps$virt"]
+ write-output "
+
+ <td class=$gainclass> $gain
+ </td> <!-- Gain -->
+
+ <!-- Apache - No Cache -->
+ <td class=apache>" $data[$app]["Apache"]["nocache"]["php1"]["tps$virt"]
"</td>
+ <td class=apache>" $data[$app]["Apache"]["nocache"]["php2"]["tps$virt"]
"</td>"
+
+ $gain = gaincalc
$data[$app]["Apache"]["nocache"]["php2"]["tps$virt"]
$data[$app]["Apache"]["nocache"]["php1"]["tps$virt"]
+ write-output "
+
+ <td class=$gainclass> $gain
+ </td> <!-- Gain -->
+
+ <!-- Apache - Cache -igbinary -->
+ <td class=apachenoigbinary>"
$data[$app]["Apache"]["cachenoigbinary"]["php1"]["tps$virt"] "</td>
+ <td class=apachenoigbinary>"
$data[$app]["Apache"]["cachenoigbinary"]["php2"]["tps$virt"] "</td>"
+
+ $gain = gaincalc
$data[$app]["Apache"]["cachenoigbinary"]["php2"]["tps$virt"]
$data[$app]["Apache"]["cachenoigbinary"]["php1"]["tps$virt"]
+ write-output "
+
+ <td class=$gainclass> $gain
+ </td> <!-- Gain -->
+
+ <!-- Apache - Cache +igbinary -->
+ <td class=apachewithigbinary>"
$data[$app]["Apache"]["cachewithigbinary"]["php1"]["tps$virt"] "</td>
+ <td class=apachewithigbinary>"
$data[$app]["Apache"]["cachewithigbinary"]["php2"]["tps$virt"] "</td>"
+
+ $gain = gaincalc
$data[$app]["Apache"]["cachewithigbinary"]["php2"]["tps$virt"]
$data[$app]["Apache"]["cachewithigbinary"]["php1"]["tps$virt"]
+ write-output "
+
+ <td class=$gainclass> $gain
+ </td> <!-- Gain -->
+ </tr>
+ "
+ } ## End Foreach
+} ## End Foreach
+
+write-output "
+</table>
+<p> </p>
+<p> </p>
+"
+
+if ( $errlog -ne "" ) {
+ write-output "<strong>Error Log:</strong> <br/>"
+ write-output "$errlog"
+}
+
+write-output "
+</body>
+</html>
+"
+
+
+*/
diff --git a/src/com/mostc/pftt/model/sapi/CliSAPIInstance.java
b/src/com/mostc/pftt/model/sapi/CliSAPIInstance.java
index 14a2555..a5ee18b 100644
--- a/src/com/mostc/pftt/model/sapi/CliSAPIInstance.java
+++ b/src/com/mostc/pftt/model/sapi/CliSAPIInstance.java
@@ -12,17 +12,21 @@ 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;
public class CliSAPIInstance extends SAPIInstance {
protected final PhpBuild build;
protected String ini_dir;
protected DebuggerManager db_mgr;
+ protected Debugger dbg;
- public CliSAPIInstance(ConsoleManager cm, AHost host, PhpBuild build,
PhpIni ini) {
+ public CliSAPIInstance(ConsoleManager cm, AHost host, ScenarioSet
scenario_set, PhpBuild build, PhpIni ini) {
super(host, ini);
this.build = build;
db_mgr = cm.getDebuggerManager();
+ if (db_mgr!=null)
+ dbg = db_mgr.newDebugger(cm, host, scenario_set, build);
}
@Override
@@ -68,17 +72,17 @@ public class CliSAPIInstance extends SAPIInstance {
}
public ExecOutput execute(EExecutableType exe_type, String name, String
php_filename, String extra_args, int timeout_sec, Map<String,String> env,
String chdir, boolean debugger_attached) throws Exception {
- return db_mgr == null ?
+ return dbg == null ?
host.execOut(createPhpCommand(exe_type,
php_filename, extra_args, debugger_attached), timeout_sec, env, chdir, true) :
- db_mgr.execOut(host, name,
createPhpCommand(exe_type, php_filename, extra_args, debugger_attached),
timeout_sec, env, chdir, true);
+ dbg.execOut(createPhpCommand(exe_type,
php_filename, extra_args, debugger_attached), timeout_sec, env, null, null);
}
public ExecHandle execThread(ConsoleManager cm, String name,
ScenarioSet scenario_set, String cmd, String chdir, Map<String,String> env,
byte[] stdin_data, boolean debugger_attached) throws Exception {
// TODO use this with CliPhpUnitTestCaseRunner
- ExecHandle eh = db_mgr == null ?
+ ExecHandle eh = dbg == null || !debugger_attached ?
host.execThread(cmd, env, chdir, stdin_data,
!debugger_attached) :
- db_mgr.execThread(host, name, cmd, env, chdir,
stdin_data, !debugger_attached);
+ dbg.execThread(cmd, env, chdir, stdin_data);
if (debugger_attached && eh instanceof LocalExecHandle) {
db_mgr.newDebugger(cm, host, scenario_set, name, build,
(LocalExecHandle)eh);
}
diff --git a/src/com/mostc/pftt/results/AbstractPhpUnitRW.java
b/src/com/mostc/pftt/results/AbstractPhpUnitRW.java
index ae3710b..bd2e977 100644
--- a/src/com/mostc/pftt/results/AbstractPhpUnitRW.java
+++ b/src/com/mostc/pftt/results/AbstractPhpUnitRW.java
@@ -37,6 +37,5 @@ public abstract class AbstractPhpUnitRW extends
AbstractTestResultRW {
public boolean isTestStatus(String test_name, EPhpUnitTestStatus
status) {
return getTestNames(status).contains(test_name);
}
- public abstract String getPath();
} // end public abstract class AbstractPhpUnitRW
diff --git a/src/com/mostc/pftt/results/AbstractPhptRW.java
b/src/com/mostc/pftt/results/AbstractPhptRW.java
index 983801e..bd88604 100644
--- a/src/com/mostc/pftt/results/AbstractPhptRW.java
+++ b/src/com/mostc/pftt/results/AbstractPhptRW.java
@@ -25,7 +25,6 @@ public abstract class AbstractPhptRW extends
AbstractTestResultRW {
public boolean isTestStatus(String test_name, EPhptTestStatus status) {
return getTestNames(status).contains(test_name);
}
- public abstract String getPath();
protected void check(EPhptTestStatus status, List<String> names) {
/*if (status==EPhptTestStatus.FAIL) {
diff --git a/src/com/mostc/pftt/results/AbstractTestResultRW.java
b/src/com/mostc/pftt/results/AbstractTestResultRW.java
index 3fc9af9..f3b90cf 100644
--- a/src/com/mostc/pftt/results/AbstractTestResultRW.java
+++ b/src/com/mostc/pftt/results/AbstractTestResultRW.java
@@ -10,4 +10,5 @@ public abstract class AbstractTestResultRW {
public abstract PhpBuildInfo getBuildInfo();
public abstract void close() throws IOException;
public abstract float passRate();
+ public abstract String getPath();
}
diff --git a/src/com/mostc/pftt/results/AbstractUITestRW.java
b/src/com/mostc/pftt/results/AbstractUITestRW.java
index 79c5a37..20849a6 100644
--- a/src/com/mostc/pftt/results/AbstractUITestRW.java
+++ b/src/com/mostc/pftt/results/AbstractUITestRW.java
@@ -31,6 +31,11 @@ public abstract class AbstractUITestRW extends
AbstractTestResultRW {
for (EUITestStatus status:EUITestStatus.values())
results_by_status.put(status, new
LinkedList<UITestResult>());
}
+
+ @Override
+ public String getPath() {
+ return dir.getAbsolutePath();
+ }
public String getWebBrowserNameAndVersion() {
return web_browser_name_and_version;
diff --git a/src/com/mostc/pftt/results/LocalConsoleManager.java
b/src/com/mostc/pftt/results/LocalConsoleManager.java
index 5173459..8675a0b 100644
--- a/src/com/mostc/pftt/results/LocalConsoleManager.java
+++ b/src/com/mostc/pftt/results/LocalConsoleManager.java
@@ -85,23 +85,39 @@ public class LocalConsoleManager implements ConsoleManager {
this.debugger_name = debugger_name;
if (LocalHost.getInstance().isWindows()) {
- if (debugger_name==null)
- db_mgr = isDebugAll()||isDebugList() ? new
WinDebugManager() : null;
- else if (debugger_name.equalsIgnoreCase("windbg"))
+ if (debugger_name==null) {
+ if (isDebugAll()||isDebugList()) {
+ db_mgr = new WinDebugManager();
+ println(EPrintType.CLUE,
"DebugManager", "Debug Using WinDbg (default)");
+ } else {
+ db_mgr = null;
+ }
+ } else if (debugger_name.equalsIgnoreCase("windbg")) {
db_mgr = new WinDebugManager();
- else if (debugger_name.equalsIgnoreCase("ttt"))
+ println(EPrintType.CLUE, "DebugManager", "Debug
Using WinDbg");
+ } else if (debugger_name.equalsIgnoreCase("ttt")) {
db_mgr = new TimeTravelTraceDebugManager();
- else
+ println(EPrintType.CLUE, "DebugManager", "Debug
Using Time Travel Tracing (TTT)");
+ } else {
db_mgr = null;
+ }
} else {
- if (debugger_name==null)
- db_mgr = isDebugAll()||isDebugList() ? new
GDBDebugManager() : null;
- else if (debugger_name.equalsIgnoreCase("gdb"))
+ if (debugger_name==null) {
+ if (isDebugAll()||isDebugList()) {
+ db_mgr = new GDBDebugManager();
+ println(EPrintType.CLUE,
"DebugManager", "Debug Using GDB (default)");
+ } else {
+ db_mgr = null;
+ }
+ } else if (debugger_name.equalsIgnoreCase("gdb")) {
db_mgr = new GDBDebugManager();
- else if (debugger_name.equalsIgnoreCase("valgrind"))
+ println(EPrintType.CLUE, "DebugManager", "Debug
Using GDB");
+ } else if (debugger_name.equalsIgnoreCase("valgrind")) {
db_mgr = new ValgrindMemoryCheckManager();
- else
+ println(EPrintType.CLUE, "DebugManager", "Debug
Using Valgrind");
+ } else {
db_mgr = null;
+ }
}
}
diff --git a/src/com/mostc/pftt/results/PhptResultWriter.java
b/src/com/mostc/pftt/results/PhptResultWriter.java
index 382a561..b065449 100644
--- a/src/com/mostc/pftt/results/PhptResultWriter.java
+++ b/src/com/mostc/pftt/results/PhptResultWriter.java
@@ -316,7 +316,7 @@ public class PhptResultWriter extends AbstractPhptRW {
serial.text(ext_name);
serial.endTag(null, "name");
}
- reportGroups(ext.test_groups);
+ // TODO temp reportGroups(ext.test_groups);
serial.endTag(null, "extension");
}
diff --git a/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
b/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
index f65335b..bceccd3 100644
--- a/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
+++ b/src/com/mostc/pftt/runner/CliPhptTestCaseRunner.java
@@ -25,6 +25,7 @@ import com.mostc.pftt.model.core.PhptTestCase;
import com.mostc.pftt.model.sapi.CliSAPIInstance;
import com.mostc.pftt.results.ConsoleManager;
import com.mostc.pftt.results.ITestResultReceiver;
+import com.mostc.pftt.results.PhpResultPack;
import com.mostc.pftt.results.PhptTestResult;
import com.mostc.pftt.runner.LocalPhptTestPackRunner.PhptThread;
import com.mostc.pftt.runner.PhptTestPreparer.PreparedPhptTestCase;
@@ -270,17 +271,16 @@ public class CliPhptTestCaseRunner extends
AbstractPhptTestCaseRunner2 {
is_timeout = true;
}
+ if (running_test_handle!=null &&
running_test_handle.cleanup_notify!=null) {
+
running_test_handle.cleanup(((PhpResultPack)twriter).getPHPT(host,
scenario_set, src_test_pack.getNameAndVersionString()));
+ }
if (!is_timeout && running_test_handle != null &&
running_test_handle.isCrashed()) {
not_crashed = false; // @see #runTest
- // TODO temp
((LocalExecHandle)running_test_handle).copyTTT();
-
int exit_code = running_test_handle.getExitCode();
twriter.addResult(host, scenario_set, src_test_pack,
notifyNotPass(new PhptTestResult(host, EPhptTestStatus.CRASH, prep.test_case,
"PFTT: exit_code="+exit_code+" status="+AHost.guessExitCodeStatus(host,
exit_code)+"\n"+output_str, null, null, null, ini, env, null, stdin_post, null,
null, null, null, output_str, null)));
- } else if (running_test_handle!=null) {
- // TODO temp
((LocalExecHandle)running_test_handle).deleteTTT();
- }
+ }
running_test_handle = null;
diff --git a/src/com/mostc/pftt/runner/LocalPhptTestPackRunner.java
b/src/com/mostc/pftt/runner/LocalPhptTestPackRunner.java
index 12743cf..51db3c7 100644
--- a/src/com/mostc/pftt/runner/LocalPhptTestPackRunner.java
+++ b/src/com/mostc/pftt/runner/LocalPhptTestPackRunner.java
@@ -47,6 +47,7 @@ import com.mostc.pftt.scenario.XDebugScenario;
public class LocalPhptTestPackRunner extends
AbstractLocalTestPackRunner<PhptActiveTestPack, PhptSourceTestPack,
PhptTestCase> {
protected final IENVINIFilter filter;
protected final boolean xdebug;
+ protected final PhptTestPreparer preparer;
public LocalPhptTestPackRunner(ConsoleManager cm, ITestResultReceiver
twriter, ScenarioSet scenario_set, PhpBuild build, AHost storage_host, AHost
runner_host, IENVINIFilter filter) {
super(cm, twriter, scenario_set, build, storage_host,
runner_host);
@@ -54,6 +55,8 @@ public class LocalPhptTestPackRunner extends
AbstractLocalTestPackRunner<PhptAct
// check once if this is using XDebug
xdebug = scenario_set.contains(XDebugScenario.class);
+
+ preparer = new PhptTestPreparer(xdebug);
}
@Override
@@ -161,6 +164,8 @@ public class LocalPhptTestPackRunner extends
AbstractLocalTestPackRunner<PhptAct
return null;
}
+ test_case.prep = preparer.prepare(test_case, runner_host,
active_test_pack);
+
return group_key;
} // end protected TestCaseGroupKey createGroupKey
@@ -237,7 +242,7 @@ public class LocalPhptTestPackRunner extends
AbstractLocalTestPackRunner<PhptAct
protected void reportGroups() {
PhptResultWriter phpt = (PhptResultWriter)
((PhpResultPackWriter)twriter).getPHPT(runner_host, scenario_set_setup,
src_test_pack.getNameAndVersionString());
- phpt.reportGroups(thread_safe_groups, non_thread_safe_exts);
+ // TODO temp phpt.reportGroups(thread_safe_groups,
non_thread_safe_exts);
}
@Override
@@ -256,7 +261,7 @@ public class LocalPhptTestPackRunner extends
AbstractLocalTestPackRunner<PhptAct
@Override
protected void runTest(TestCaseGroupKey group_key, PhptTestCase
test_case, boolean debugger_attached) throws IOException, Exception, Throwable {
- r = sapi_scenario.createPhptTestCaseRunner(this,
group_key, test_case, cm, twriter, runner_host, scenario_set_setup, build,
src_test_pack, active_test_pack, xdebug, debugger_attached);
+ r = sapi_scenario.createPhptTestCaseRunner(this,
group_key, test_case.prep, cm, twriter, runner_host, scenario_set_setup, build,
src_test_pack, active_test_pack, xdebug, debugger_attached);
twriter.notifyStart(runner_host, scenario_set_setup,
src_test_pack, test_case);
r.runTest(cm, this, LocalPhptTestPackRunner.this);
}
diff --git a/src/com/mostc/pftt/scenario/CLIScenario.java
b/src/com/mostc/pftt/scenario/CLIScenario.java
index 9cbcab9..30c81aa 100644
--- a/src/com/mostc/pftt/scenario/CLIScenario.java
+++ b/src/com/mostc/pftt/scenario/CLIScenario.java
@@ -118,7 +118,7 @@ public class CliScenario extends SAPIScenario {
// -for WEB SERVERS, have to set ENV vars on each
web server instance
// @see CliPhptTestCaseRunner#prepare
//
- CliSAPIInstance sapi = new CliSAPIInstance(cm, host,
build, ini);
+ CliSAPIInstance sapi = new CliSAPIInstance(cm, host,
scenario_set_setup.getScenarioSet(), build, ini);
return new CliTestCaseGroupKey(sapi, ini, null);
} else if (group_key!=null &&
group_key.getPhpIni().isDefault()) {
@@ -128,7 +128,7 @@ public class CliScenario extends SAPIScenario {
filter.prepareIni(cm, ini);
- CliSAPIInstance sapi = new CliSAPIInstance(cm, host,
build, ini);
+ CliSAPIInstance sapi = new CliSAPIInstance(cm, host,
scenario_set_setup.getScenarioSet(), build, ini);
return new CliTestCaseGroupKey(sapi, ini, null);
}
diff --git a/src/com/mostc/pftt/util/DebuggerManager.java
b/src/com/mostc/pftt/util/DebuggerManager.java
index a717e80..212fe71 100644
--- a/src/com/mostc/pftt/util/DebuggerManager.java
+++ b/src/com/mostc/pftt/util/DebuggerManager.java
@@ -15,6 +15,7 @@ import com.mostc.pftt.model.core.PhpBuild;
import com.mostc.pftt.model.core.PhptTestCase;
import com.mostc.pftt.results.ConsoleManager;
import com.mostc.pftt.results.EPrintType;
+import com.mostc.pftt.runner.AbstractTestPackRunner.TestPackRunnerThread;
import com.mostc.pftt.scenario.Scenario;
import com.mostc.pftt.scenario.ScenarioSet;
@@ -24,7 +25,6 @@ import com.mostc.pftt.scenario.ScenarioSet;
*
*/
-// XXX support for GDB on Linux
public abstract class DebuggerManager {
protected String src_path, debug_path;
@@ -200,57 +200,46 @@ public abstract class DebuggerManager {
int timeout_sec, Map<String, String> env,
byte[] stdin_post,
Charset charset, String current_dir)
throws IllegalStateException, Exception {
- // TODO Auto-generated method stub
- return false;
+ return execOut(cmd, timeout_sec, env, stdin_post,
charset).isSuccess();
}
@Override
- public ExecHandle execThread(String commandline) throws
Exception {
- // TODO Auto-generated method stub
- return null;
+ public boolean exec(ConsoleManager cm, String ctx_str,
+ String commandline, int timeout, Map<String,
String> env,
+ byte[] stdin, Charset charset, String chdir,
+ TestPackRunnerThread thread, int
thread_slow_sec)
+ throws Exception {
+ return execOut(commandline, timeout, env, stdin,
charset).isSuccess();
}
-
+
@Override
- public ExecHandle execThread(String commandline, byte[]
stdin_data)
- throws Exception {
- // TODO Auto-generated method stub
- return null;
+ public ExecHandle execThread(String commandline) throws
Exception {
+ return execThread(commandline, null, null, null);
}
@Override
- public ExecHandle execThread(String commandline, String chdir)
- throws Exception {
- // TODO Auto-generated method stub
- return null;
+ public ExecHandle execThread(String commandline, byte[]
stdin_data) throws Exception {
+ return execThread(commandline, null, null, stdin_data);
}
@Override
- public ExecHandle execThread(String commandline, String chdir,
- byte[] stdin_data) throws Exception {
- // TODO Auto-generated method stub
- return null;
+ public ExecHandle execThread(String commandline, String chdir)
throws Exception {
+ return execThread(commandline, null, chdir, null);
}
@Override
- public ExecHandle execThread(String commandline,
- Map<String, String> env, byte[] stdin_data)
throws Exception {
- // TODO Auto-generated method stub
- return null;
+ public ExecHandle execThread(String commandline, String chdir,
byte[] stdin_data) throws Exception {
+ return execThread(commandline, null, chdir, stdin_data);
}
@Override
- public ExecHandle execThread(String commandline,
- Map<String, String> env, String chdir) throws
Exception {
- // TODO Auto-generated method stub
- return null;
+ public ExecHandle execThread(String commandline, Map<String,
String> env, byte[] stdin_data) throws Exception {
+ return execThread(commandline, env, null, stdin_data);
}
@Override
- public ExecHandle execThread(String commandline,
- Map<String, String> env, String chdir, byte[]
stdin_data)
- throws Exception {
- // TODO Auto-generated method stub
- return null;
+ public ExecHandle execThread(String commandline, Map<String,
String> env, String chdir) throws Exception {
+ return execThread(commandline, env, chdir, null);
}
@Override
@@ -268,6 +257,11 @@ public abstract class DebuggerManager {
return createRunRequest(cm,
ctx_clazz==null?null:ctx_clazz.getSimpleName());
}
+ } // end public static abstract class Debugger
+
+ public Debugger newDebugger(ConsoleManager cm, AHost host,
+ ScenarioSet scenario_set, PhpBuild build) {
+ return null;
}
} // end public abstract class DebuggerManager
diff --git a/src/com/mostc/pftt/util/GDBDebugManager.java
b/src/com/mostc/pftt/util/GDBDebugManager.java
index 111a3c9..b8c833a 100644
--- a/src/com/mostc/pftt/util/GDBDebugManager.java
+++ b/src/com/mostc/pftt/util/GDBDebugManager.java
@@ -67,6 +67,14 @@ public class GDBDebugManager extends DebuggerManager {
// TODO Auto-generated method stub
return false;
}
+
+ @Override
+ public ExecHandle execThread(String commandline,
+ Map<String, String> env, String chdir, byte[]
stdin_data)
+ throws Exception {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
diff --git a/src/com/mostc/pftt/util/TimeTravelTraceDebugManager.java
b/src/com/mostc/pftt/util/TimeTravelTraceDebugManager.java
new file mode 100644
index 0000000..3b78f10
--- /dev/null
+++ b/src/com/mostc/pftt/util/TimeTravelTraceDebugManager.java
@@ -0,0 +1,179 @@
+package com.mostc.pftt.util;
+
+import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.mostc.pftt.host.AHost;
+import com.mostc.pftt.host.AHost.ExecHandle;
+import com.mostc.pftt.host.AHost.IExecHandleCleanupNotify;
+import com.mostc.pftt.host.ExecOutput;
+import com.mostc.pftt.host.Host;
+import com.mostc.pftt.host.ICrashDetector;
+import com.mostc.pftt.model.core.PhpBuild;
+import com.mostc.pftt.results.AbstractTestResultRW;
+import com.mostc.pftt.results.ConsoleManager;
+import com.mostc.pftt.results.EPrintType;
+import com.mostc.pftt.scenario.ScenarioSet;
+
+/** Handles integration with Time-Travel-Tracing, a debugging feature on
Windows.
+ *
+ * For info on how to use a TTT trace (PFTT takes care of recording them for
you)
+ * @see http://sharepoint/sites/cse/tttwiki/ (internal Microsoft only :()
+ *
+ */
+
+public class TimeTravelTraceDebugManager extends WindowsDebuggerToolsManager {
+
+ @Override
+ public Debugger newDebugger(ConsoleManager cm, AHost host, ScenarioSet
scenario_set, Object server_name, PhpBuild build, int process_id, ExecHandle
process) {
+ return null;
+ }
+
+ protected boolean displayed_tips = false;
+ protected void displayTips(ConsoleManager cm) {
+ if (cm==null)
+ return;
+ if (displayed_tips)
+ return;
+ displayed_tips = true;
+ cm.println(EPrintType.CLUE, getClass(), "PFTT is recording
Time-Travel Traces of crashed processes in Result-Pack");
+ cm.println(EPrintType.CLUE, getClass(), "");
+ cm.println(EPrintType.CLUE, getClass(), "Common TTT Replay
commands");
+ cm.println(EPrintType.CLUE, getClass(), "");
+ cm.println(EPrintType.CLUE, getClass(), "Open TTT in WinDebug
using File > Open Crash Dump");
+ cm.println(EPrintType.CLUE, getClass(), "!idna.events - shows
event timeline including thread creation");
+ cm.println(EPrintType.CLUE, getClass(), "gu - run selected
thread until unhandled exception");
+ cm.println(EPrintType.CLUE, getClass(), "k - stack trace");
+ cm.println(EPrintType.CLUE, getClass(), "");
+ cm.println(EPrintType.CLUE, getClass(), "Problems loading idna
DLL (WinDebug extension) into WinDebug:");
+ cm.println(EPrintType.CLUE, getClass(), "1. copy C:\\Program
Files\\Debugging Tools to c:\\debuggers (windbg commands can't have ` ` or
\")");
+ cm.println(EPrintType.CLUE, getClass(), "2. .extpath +
c:\\debuggers\\TTT");
+ cm.println(EPrintType.CLUE, getClass(), "3.
`!c:\\debuggers\\TTT\\idna` instead of `!idna`");
+ cm.println(EPrintType.CLUE, getClass(), "fe
!c:\\debuggers\\TTT\\idna.position");
+ }
+
+ public Debugger newDebugger(ConsoleManager cm, AHost host, ScenarioSet
scenario_set, PhpBuild build) {
+ String ttt_exe = null;
+ for ( String path : getToolPaths(host, build,
"TTT\\TTTracer.exe") ) {
+ if (host.exists(path)) {
+ ttt_exe = path;
+ break;
+ }
+ }
+ if (ttt_exe==null)
+ return null;
+
+ displayTips(cm);
+ return new TTTDebugger(host, ttt_exe);
+ }
+
+ protected class TTTDebugger extends Debugger {
+ protected final AHost host;
+ // c:\\Program Files (x86)\\Debugging Tools for Windows
(x86)\\TTT\\TTTracer.exe
+ protected final String ttt_exe;
+
+ protected TTTDebugger(AHost host, String ttt_exe) {
+ this.host = host;
+ this.ttt_exe = ttt_exe;
+ }
+
+ @Override
+ public ExecOutput execOut(String cmd, int timeout_sec,
+ Map<String, String> object, byte[] stdin_post,
Charset charset)
+ throws IllegalStateException, Exception {
+ final String ttt_file =
createTTTFilenameFromCommand(host, cmd);
+ ExecOutput eo = host.execOut(cmd, timeout_sec, object,
stdin_post, charset);
+ handleCleanup(ttt_file, eo, null);
+ return eo;
+ }
+
+ @Override
+ public RunRequest createRunRequest(ConsoleManager cm, String
ctx_str) {
+ return host.createRunRequest(cm, ctx_str);
+ }
+
+ @Override
+ public ExecOutput execOut(RunRequest req) {
+ final String ttt_file =
createTTTFilenameFromCommand(host, req.getCommandline());
+ ExecOutput eo = host.execOut(req);
+ handleCleanup(ttt_file, eo, null);
+ return eo;
+ }
+
+ @Override
+ public ExecHandle execThread(RunRequest req) {
+ final String ttt_file =
createTTTFilenameFromCommand(host, req.getCommandline());
+ return handleThread(ttt_file, host.execThread(req));
+ }
+
+ @Override
+ public void close(ConsoleManager cm) {
+
+ }
+
+ @Override
+ public boolean isRunning() {
+ return host.isOpen();
+ }
+
+ @Override
+ public ExecHandle execThread(String commandline,
+ Map<String, String> env, String chdir, byte[]
stdin_data)
+ throws Exception {
+ final String ttt_file =
createTTTFilenameFromCommand(host, commandline);
+ return handleThread(ttt_file,
host.execThread(wrapCommand(ttt_exe, ttt_file, commandline), env, chdir,
stdin_data));
+ }
+
+ protected ExecHandle handleThread(final String ttt_file,
ExecHandle eh) {
+ eh.cleanup_notify = new IExecHandleCleanupNotify() {
+ @Override
+ public void cleanupNotify(ExecHandle
eh, AbstractTestResultRW rw) {
+ handleCleanup(ttt_file, eh, rw);
+ }
+ };
+ return eh;
+ }
+
+ protected void handleCleanup(String ttt_file, ICrashDetector
eh, AbstractTestResultRW rw) {
+ if (eh.isCrashed()) {
+ if (rw!=null) {
+ try {
+ // move TTT file to result-pack
(we want it, its a crash)
+ // and rename it to .run
+ host.move(ttt_file,
rw.getPath()+"/"+Host.basename(ttt_file)+".run");
+ } catch ( Exception ex ) {
+ ex.printStackTrace();
+ }
+ }
+ } else {
+ try {
+ host.delete(ttt_file);
+ } catch ( Exception ex ) {}
+ }
+ }
+
+ } // end protected class TTTDebugger
+
+ AtomicInteger i = new AtomicInteger(0);
+ protected String createTTTFilenameFromCommand(AHost host, String cmd) {
+ if (cmd.startsWith("\"")) {
+ int i = cmd.indexOf('"', 1);
+ cmd = cmd.substring(1, i);
+ } else {
+ int i = cmd.indexOf(' ');
+ cmd = cmd.substring(1, i);
+ }
+ String name = Host.basename(cmd);
+
+
+ return host.getTempDir()+"\\"+name+i.incrementAndGet()+".run";
+ }
+
+ protected String wrapCommand(String ttt_exe, String ttt_file, String
cmd) {
+ // passThroughExit => critical to detect crash
+ // launch => critical to actually run the process
+ return "\""+ttt_exe+"\" -passThroughExit -noUI -timer 60
-autoStart -saveCrash "+ttt_file+" -launch \"" + cmd +"\"";
+ }
+
+} // end public class TimeTravelTraceDebugManager
diff --git a/src/com/mostc/pftt/util/TimerUtil.java
b/src/com/mostc/pftt/util/TimerUtil.java
index c5d4c5c..c9675a3 100644
--- a/src/com/mostc/pftt/util/TimerUtil.java
+++ b/src/com/mostc/pftt/util/TimerUtil.java
@@ -73,8 +73,8 @@ public final class TimerUtil {
* many handles, it will wait a long time before allocating more, which
delays thread creation
* (which in turn can delay things like killing off timed out
processes, which in turn frees up handles).
*
- * Instead, a bunch of threads are preallocated in a pool at startup.
This gets one of
- * those threads and has it run the given Runnable.
+ * Instead, some threads are preallocated in a pool at startup to help
ensure that a thread
+ * can be created when its needed.
*
* Note: you may not call #start or #setDaemon on the returned Thread.
you will get an IllegalThreadStateException if you do.
*
diff --git a/src/com/mostc/pftt/util/ValgrindMemoryCheckManager.java
b/src/com/mostc/pftt/util/ValgrindMemoryCheckManager.java
index be952bf..ee1281a 100644
--- a/src/com/mostc/pftt/util/ValgrindMemoryCheckManager.java
+++ b/src/com/mostc/pftt/util/ValgrindMemoryCheckManager.java
@@ -101,6 +101,14 @@ public class ValgrindMemoryCheckManager extends
DebuggerManager {
return null; // TODO temp
}
+
+ @Override
+ public ExecHandle execThread(String commandline,
+ Map<String, String> env, String chdir, byte[]
stdin_data)
+ throws Exception {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
diff --git a/src/com/mostc/pftt/util/WinDebugManager.java
b/src/com/mostc/pftt/util/WinDebugManager.java
index a8fb35c..d95b2b1 100644
--- a/src/com/mostc/pftt/util/WinDebugManager.java
+++ b/src/com/mostc/pftt/util/WinDebugManager.java
@@ -31,7 +31,7 @@ import com.mostc.pftt.scenario.ScenarioSet;
*
*/
-public class WinDebugManager extends DebuggerManager {
+public class WinDebugManager extends WindowsDebuggerToolsManager {
private String win_dbg_exe;
private AHost win_dbg_host;
private boolean displayed_windbg_tips = false;
@@ -76,9 +76,10 @@ public class WinDebugManager extends DebuggerManager {
protected void displayWindebugTips(ConsoleManager cm) {
cm.println(EPrintType.TIP, getClass(), " WinDebug Command
Referrence: http://www.windbg.info/doc/1-common-cmds.html");
- cm.println(EPrintType.TIP, getClass(), " WinDebug command: k
- show callstack");
- cm.println(EPrintType.TIP, getClass(), " WinDebug command: g
- go (until next exception)");
- cm.println(EPrintType.TIP, getClass(), " WinDebug command:
<F9> - set breakpoint");
+ cm.println(EPrintType.TIP, getClass(), " WinDebug command: k
- show callstack");
+ cm.println(EPrintType.TIP, getClass(), " WinDebug command: g
- go (until next exception)");
+ cm.println(EPrintType.TIP, getClass(), " WinDebug command:
.dump /ma <filename> - create coredump file");
+ cm.println(EPrintType.TIP, getClass(), " WinDebug command:
<F9> - set breakpoint");
}
public static class WinDebug extends Debugger {
@@ -203,6 +204,14 @@ public class WinDebugManager extends DebuggerManager {
// TODO Auto-generated method stub
return null;
}
+
+ @Override
+ public ExecHandle execThread(String commandline,
+ Map<String, String> env, String chdir, byte[]
stdin_data)
+ throws Exception {
+ // TODO Auto-generated method stub
+ return null;
+ }
} // end public static class WinDebug
@@ -215,24 +224,9 @@ public class WinDebugManager extends DebuggerManager {
* @return
*/
public static String[] getWinDebugPaths(Host host, PhpBuild build) {
- // use x86 windebug for x86 builds and x64 windebug edition for
x64 builds!
- // (can debug with different windebug editions, but WER popup
requires that the architectures match)
- // @see HostEnvUtil
- if (build.isX86()) {
- //
- return new String[] {
- host.getSystemDrive()+"\\Program Files
(x86)\\Debugging Tools for Windows\\WinDbg.exe",
- host.getSystemDrive()+"\\Program Files
(x86)\\Debugging Tools for Windows (x86)\\WinDbg.exe"
- };
- } else {
- return new String[] {
- host.getSystemDrive()+"\\Program
Files\\Debugging Tools for Windows (x64)\\WinDbg.exe",
- host.getSystemDrive()+"\\Program
Files\\Debugging Tools for Windows\\WinDbg.exe",
- host.getSystemDrive()+"\\Program
Files\\Debugging Tools for Windows (x86)\\WinDbg.exe"
- };
- }
+ return getToolPaths(host, build, "windbg.exe");
}
-
+
/** returns the path that WinDebug is installed at, or returns null if
windebug is not found.
*
* @see #getWinDebugPaths
diff --git a/src/com/mostc/pftt/util/WindowsDebuggerToolsManager.java
b/src/com/mostc/pftt/util/WindowsDebuggerToolsManager.java
new file mode 100644
index 0000000..844a3f7
--- /dev/null
+++ b/src/com/mostc/pftt/util/WindowsDebuggerToolsManager.java
@@ -0,0 +1,27 @@
+package com.mostc.pftt.util;
+
+import com.mostc.pftt.host.Host;
+import com.mostc.pftt.model.core.PhpBuild;
+
+public abstract class WindowsDebuggerToolsManager extends DebuggerManager {
+
+ public static String[] getToolPaths(Host host, PhpBuild build, String
exe_file) {
+ // use x86 windebug for x86 builds and x64 windebug edition for
x64 builds!
+ // (can debug with different windebug editions, but WER popup
requires that the architectures match)
+ // @see HostEnvUtil
+ if (build.isX86()) {
+ //
+ return new String[] {
+ host.getSystemDrive()+"\\Program Files
(x86)\\Debugging Tools for Windows\\"+exe_file,
+ host.getSystemDrive()+"\\Program Files
(x86)\\Debugging Tools for Windows (x86)\\"+exe_file
+ };
+ } else {
+ return new String[] {
+ host.getSystemDrive()+"\\Program
Files\\Debugging Tools for Windows (x64)\\"+exe_file,
+ host.getSystemDrive()+"\\Program
Files\\Debugging Tools for Windows\\"+exe_file,
+ host.getSystemDrive()+"\\Program
Files\\Debugging Tools for Windows (x86)\\"+exe_file
+ };
+ }
+ }
+
+}