diff options
author | Jiri Vanek <[email protected]> | 2012-07-02 15:08:21 +0200 |
---|---|---|
committer | Jiri Vanek <[email protected]> | 2012-07-02 15:08:21 +0200 |
commit | d71e609b1279077474135364ed4bb223e068d0bd (patch) | |
tree | 28544c882d03f00e270b8b6f1d15130dea63e17c /tests/test-extensions/net/sourceforge/jnlp | |
parent | d11831804f320ce432b904032d5cfbf00c1a198b (diff) |
Refactored reproducers directry structure
Diffstat (limited to 'tests/test-extensions/net/sourceforge/jnlp')
29 files changed, 3166 insertions, 0 deletions
diff --git a/tests/test-extensions/net/sourceforge/jnlp/ContentReader.java b/tests/test-extensions/net/sourceforge/jnlp/ContentReader.java new file mode 100644 index 0000000..464b778 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/ContentReader.java @@ -0,0 +1,133 @@ +/* ContentReader.java +Copyright (C) 2011,2012 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package net.sourceforge.jnlp; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +/** + * Class to read content of stdout/stderr of process, and to cooperate with its running/terminated/finished statuses. + */ +class ContentReader implements Runnable { + + StringBuilder sb = new StringBuilder(); + private final InputStream is; + private boolean done; + ContentReaderListener listener; + + public String getContent() { + return sb.toString(); + } + + public ContentReader(InputStream is) throws IOException { + this.is = is; + } + + public ContentReader(InputStream is, ContentReaderListener l) throws IOException { + this.is = is; + this.listener = l; + } + + public void setListener(ContentReaderListener listener) { + this.listener = listener; + } + + public ContentReaderListener getListener() { + return listener; + } + + /** + * Blocks until the copy is complete, or until the thread is interrupted + */ + public synchronized void waitUntilDone() throws InterruptedException { + boolean interrupted = false; + // poll interrupted flag, while waiting for copy to complete + while (!(interrupted = Thread.interrupted()) && !done) { + wait(1000); + } + if (interrupted) { + ServerAccess.logNoReprint("Stream copier: throwing InterruptedException"); + //throw new InterruptedException(); + } + } + + @Override + public void run() { + try { + Reader br = new InputStreamReader(is, "UTF-8"); + StringBuilder line = new StringBuilder(); + while (true) { + int s = br.read(); + if (s < 0) { + if (line.length() > 0 && listener != null) { + listener.lineReaded(line.toString()); + } + break; + } + char ch = (char) s; + sb.append(ch); + line.append(ch); + if (ch == '\n') { + if (listener != null) { + listener.lineReaded(line.toString()); + } + line = new StringBuilder(); + } + if (listener != null) { + listener.charReaded(ch); + } + } + //do not want to bother output with terminations + //mostly compaling when assassin kill the process about StreamClosed + //do not want to bother output with terminations + //mostly compaling when assassin kill the process about StreamClosed + } catch (Exception ex) { + // logException(ex); + } finally { + try { + is.close(); + } catch (Exception ex) { + // ex.printStackTrace(); + } finally { + done = true; + } + } + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/ContentReaderListener.java b/tests/test-extensions/net/sourceforge/jnlp/ContentReaderListener.java new file mode 100644 index 0000000..4427d84 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/ContentReaderListener.java @@ -0,0 +1,45 @@ +/* ContentReaderListener.java +Copyright (C) 2011,2012 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package net.sourceforge.jnlp; + +public interface ContentReaderListener { + + public void charReaded(char ch); + public void lineReaded(String s); + +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/LogItem.java b/tests/test-extensions/net/sourceforge/jnlp/LogItem.java new file mode 100644 index 0000000..dd99c04 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/LogItem.java @@ -0,0 +1,71 @@ +/* LogItem.java +Copyright (C) 2011,2012 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package net.sourceforge.jnlp; + +import java.util.Date; + +class LogItem { + + public final Date timeStamp = new Date(); + public final StackTraceElement[] fullTrace = Thread.currentThread().getStackTrace(); + public final String text; + private static final String ITEM_ELEMENT = "item"; + private static final String ITEM_ID_ATTRIBUTE = "id"; + private static final String STAMP_ELEMENT = "stamp"; + private static final String TEXT_ELEMENT = "text"; + private static final String FULLTRACE_ELEMENT = "fulltrace"; + + public LogItem(String text) { + this.text = text; + } + + public StringBuilder toStringBuilder(int id) { + StringBuilder sb = new StringBuilder(); + sb.append(" <" + ITEM_ELEMENT + " " + ITEM_ID_ATTRIBUTE + "=\"").append(id).append("\">\n"); + sb.append(" <" + STAMP_ELEMENT + "><![CDATA[").append(timeStamp.toString()).append("]]></" + STAMP_ELEMENT + ">\n"); + sb.append(" <" + TEXT_ELEMENT + "><![CDATA[\n").append(text).append("\n]]></" + TEXT_ELEMENT + ">\n"); + sb.append(" <" + FULLTRACE_ELEMENT + "><![CDATA[\n"); + //five methods since call in log methods + getStacktrace method + for (int i = 6; i < fullTrace.length; i++) { + sb.append(fullTrace[i].toString()).append("\n"); + } + sb.append("\n]]> </" + FULLTRACE_ELEMENT + ">\n"); + sb.append(" </" + ITEM_ELEMENT + ">\n"); + return sb; + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/LoggingBottleneck.java b/tests/test-extensions/net/sourceforge/jnlp/LoggingBottleneck.java new file mode 100644 index 0000000..3f4de4b --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/LoggingBottleneck.java @@ -0,0 +1,215 @@ +/* LoggingBottleneck.java +Copyright (C) 2011,2012 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package net.sourceforge.jnlp; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import net.sourceforge.jnlp.annotations.TestInBrowsers; +import net.sourceforge.jnlp.browsertesting.BrowserTest; +import net.sourceforge.jnlp.browsertesting.Browsers; + +public class LoggingBottleneck { + + /** + * default singleton + */ + private static LoggingBottleneck loggingBottleneck; + private static final File DEFAULT_LOG_FILE = new File("ServerAccess-logs.xml"); + private static final File DEFAULT_STDERR_FILE = new File("stderr.log"); + private static final File DEFAULT_STDOUT_FILE = new File("stdout.log"); + private static final File DEFAULT_STDLOGS_FILE = new File("all.log"); + private static final String LOGS_ELEMENT = "logs"; + private static final String CLASSLOG_ELEMENT = "classlog"; + private static final String CLASSNAME_ATTRIBUTE = "className"; + private static final String TESTLOG_ELEMENT = "testLog"; + private static final String TESTMETHOD_ATTRIBUTE = "testMethod"; + private static final String FULLID_ATTRIBUTE = "fullId"; + private BufferedWriter DEFAULT_STDERR_WRITER; + private BufferedWriter DEFAULT_STDOUT_WRITER; + private BufferedWriter DEFAULT_STDLOGS_WRITER; + /** + * This is static copy of name of id of currentBrowser for logging purposes + */ + private String loggedBrowser = Browsers.none.toString(); + /** + * map of classes, each have map of methods, each have errorlist, outLIst, and allList (allist contains also not std or err messages) + * class.testMethod.logs + */ + final Map<String, Map<String, TestsLogs>> processLogs = new HashMap<String, Map<String, TestsLogs>>(100); + private boolean added = false; + + public static LoggingBottleneck getDefaultLoggingBottleneck() { + if (loggingBottleneck == null) { + loggingBottleneck = new LoggingBottleneck(); + } + return loggingBottleneck; + + } + + private LoggingBottleneck() { + try { + DEFAULT_STDOUT_WRITER = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DEFAULT_STDOUT_FILE))); + DEFAULT_STDERR_WRITER = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DEFAULT_STDERR_FILE))); + DEFAULT_STDLOGS_WRITER = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DEFAULT_STDLOGS_FILE))); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + void writeXmlLog() throws FileNotFoundException, IOException { + writeXmlLog(DEFAULT_LOG_FILE); + } + + void writeXmlLog(File f) throws FileNotFoundException, IOException { + Writer w = new OutputStreamWriter(new FileOutputStream(f)); + Set<Entry<String, Map<String, TestsLogs>>> classes = processLogs.entrySet(); + w.write("<" + LOGS_ELEMENT + ">"); + for (Entry<String, Map<String, TestsLogs>> classLog : classes) { + String className = classLog.getKey(); + w.write("<" + CLASSLOG_ELEMENT + " " + CLASSNAME_ATTRIBUTE + "=\"" + className + "\">"); + Set<Entry<String, TestsLogs>> testsLogs = classLog.getValue().entrySet(); + for (Entry<String, TestsLogs> testLog : testsLogs) { + String testName = testLog.getKey(); + String testLogs = testLog.getValue().toString(); + w.write("<" + TESTLOG_ELEMENT + " " + TESTMETHOD_ATTRIBUTE + "=\"" + testName + "\" " + FULLID_ATTRIBUTE + "=\"" + className + "." + testName + "\" >"); + w.write(testLogs); + w.write("</" + TESTLOG_ELEMENT + ">"); + } + w.write("</" + CLASSLOG_ELEMENT + ">"); + } + w.write("</" + LOGS_ELEMENT + ">"); + w.flush(); + w.close(); + } + + void addToXmlLog(String message, boolean printToOut, boolean printToErr, StackTraceElement ste) { + Map<String, TestsLogs> classLog = processLogs.get(ste.getClassName()); + if (classLog == null) { + classLog = new HashMap<String, TestsLogs>(50); + processLogs.put(ste.getClassName(), classLog); + } + String methodBrowseredName = ste.getMethodName(); + methodBrowseredName = modifyMethodWithForBrowser(methodBrowseredName, ste.getClassName()); + TestsLogs methodLog = classLog.get(methodBrowseredName); + if (methodLog == null) { + methodLog = new TestsLogs(); + classLog.put(methodBrowseredName, methodLog); + } + if (!added) { + Runtime.getRuntime().addShutdownHook(new Thread() { + + @Override + public void run() { + try { + LoggingBottleneck.getDefaultLoggingBottleneck().writeXmlLog(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + }); + added = true; + } + methodLog.add(printToErr, printToOut, message); + } + + public String modifyMethodWithForBrowser(String methodBrowseredName, String className) { + try { + Class clazz = Class.forName(className); + /* + * By using this isAssignable to ensure corect class before invocation, + * then we lost possibility to track manualy set browsers, but it is correct, + * as method description is set only when annotation is used + */ + if (clazz != null && BrowserTest.class.isAssignableFrom(clazz)) { + Method testMethod = clazz.getMethod(methodBrowseredName); + if (testMethod != null) { + TestInBrowsers tib = testMethod.getAnnotation(TestInBrowsers.class); + if (tib != null) { + methodBrowseredName = methodBrowseredName + " - " + loggedBrowser; + } + } + } + } catch (Throwable ex) { + ex.printStackTrace(); + } + return methodBrowseredName; + } + + public void setLoggedBrowser(String loggedBrowser) { + this.loggedBrowser = loggedBrowser; + } + + public void logIntoPlaintextLog(String message, boolean printToOut, boolean printToErr) { + try { + if (printToOut) { + LoggingBottleneck.getDefaultLoggingBottleneck().stdout(message); + } + if (printToErr) { + LoggingBottleneck.getDefaultLoggingBottleneck().stderr(message); + } + LoggingBottleneck.getDefaultLoggingBottleneck().stdeall(message); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + private void stdout(String idded) throws IOException { + DEFAULT_STDOUT_WRITER.write(idded); + DEFAULT_STDOUT_WRITER.newLine(); + } + + private void stderr(String idded) throws IOException { + DEFAULT_STDERR_WRITER.write(idded); + DEFAULT_STDERR_WRITER.newLine(); + } + + private void stdeall(String idded) throws IOException { + DEFAULT_STDLOGS_WRITER.write(idded); + DEFAULT_STDLOGS_WRITER.newLine(); + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/ProcessAssasin.java b/tests/test-extensions/net/sourceforge/jnlp/ProcessAssasin.java new file mode 100644 index 0000000..c910311 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/ProcessAssasin.java @@ -0,0 +1,159 @@ +/* ProcessAssasin.java +Copyright (C) 2011,2012 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package net.sourceforge.jnlp; + +/** + * class which timeout any ThreadedProcess. This killing of 'thread with process' replaced not working process.destroy(). + */ +class ProcessAssasin extends Thread { + + long timeout; + private final ThreadedProcess p; + //false == is disabled:( + private boolean canRun = true; + private boolean wasTerminated = false; + /** + * if this is true, then process is not destroyed after timeout, but just left to its own destiny. + * Its stdout/err is no longer recorded, and it is leaking system resources until it dies by itself + * The contorl is returned to main thread with all informations recorded untill now. + * You will be able to listen to std out from listeners still + */ + private boolean skipInstedOfDesroy = false; + + public ProcessAssasin(ThreadedProcess p, long timeout) { + this.p = (p); + this.timeout = timeout; + } + + public ProcessAssasin(ThreadedProcess p, long timeout, boolean skipInstedOfDesroy) { + this.p = (p); + this.timeout = timeout; + this.skipInstedOfDesroy = skipInstedOfDesroy; + } + + public void setCanRun(boolean canRun) { + this.canRun = canRun; + if (p != null) { + if (p.getP() != null) { + ServerAccess.logNoReprint("Stopping assassin for" + p.toString() + " " + p.getP().toString() + " " + p.getCommandLine() + ": "); + } else { + ServerAccess.logNoReprint("Stopping assassin for" + p.toString() + " " + p.getCommandLine() + ": "); + } + } else { + ServerAccess.logNoReprint("Stopping assassin for null job: "); + } + } + + public boolean isCanRun() { + return canRun; + } + + public boolean wasTerminated() { + return wasTerminated; + } + + public void setSkipInstedOfDesroy(boolean skipInstedOfDesroy) { + this.skipInstedOfDesroy = skipInstedOfDesroy; + } + + public boolean isSkipInstedOfDesroy() { + return skipInstedOfDesroy; + } + + @Override + public void run() { + long startTime = System.nanoTime() / ServerAccess.NANO_TIME_DELIMITER; + while (canRun) { + try { + long time = System.nanoTime() / ServerAccess.NANO_TIME_DELIMITER; + //ServerAccess.logOutputReprint(time - startTime); + //ServerAccess.logOutputReprint((time - startTime) > timeout); + if ((time - startTime) > timeout) { + try { + if (p != null) { + if (p.getP() != null) { + ServerAccess.logErrorReprint("Timed out " + p.toString() + " " + p.getP().toString() + " .. killing " + p.getCommandLine() + ": "); + } else { + ServerAccess.logErrorReprint("Timed out " + p.toString() + " " + "null .. killing " + p.getCommandLine() + ": "); + } + wasTerminated = true; + p.interrupt(); + while (!ServerAccess.terminated.contains(p)) { + Thread.sleep(100); + } + if (p.getP() != null) { + try { + if (!skipInstedOfDesroy) { + p.getP().destroy(); + } + } catch (Throwable ex) { + if (p.deadlyException == null) { + p.deadlyException = ex; + } + ex.printStackTrace(); + } + } + if (p.getP() != null) { + ServerAccess.logErrorReprint("Timed out " + p.toString() + " " + p.getP().toString() + " .. killed " + p.getCommandLine()); + } else { + ServerAccess.logErrorReprint("Timed out " + p.toString() + " null .. killed " + p.getCommandLine()); + } + } else { + ServerAccess.logErrorReprint("Timed out null job"); + } + break; + } finally { + p.setDestoyed(true); + } + } + Thread.sleep(100); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + if (p != null) { + if (p.getP() != null) { + ServerAccess.logNoReprint("assassin for" + p.toString() + " " + p.getP().toString() + " .. done " + p.getCommandLine() + " termination " + wasTerminated); + } else { + ServerAccess.logNoReprint("assassin for" + p.toString() + " null .. done " + p.getCommandLine() + " termination " + wasTerminated); + } + } else { + ServerAccess.logNoReprint("assassin for non existing job termination " + wasTerminated); + } + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/ProcessResult.java b/tests/test-extensions/net/sourceforge/jnlp/ProcessResult.java new file mode 100644 index 0000000..d436f72 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/ProcessResult.java @@ -0,0 +1,69 @@ +/* ProcessResult.java +Copyright (C) 2011,2012 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package net.sourceforge.jnlp; + +/** + * artefacts what are left by finished process + */ +public class ProcessResult { + + public final String stdout; + public final String notFilteredStdout; + public final String stderr; + public final Process process; + public final Integer returnValue; + public final boolean wasTerminated; + /* + * possible exception which caused Process not to be launched + */ + public final Throwable deadlyException; + + public ProcessResult(String stdout, String stderr, Process process, boolean wasTerminated, Integer r, Throwable deadlyException) { + this.notFilteredStdout = stdout; + if (stdout == null) { + this.stdout = null; + } else { + this.stdout = stdout.replaceAll("EMMA:.*\n?", ""); + } + this.stderr = stderr; + this.process = process; + this.wasTerminated = wasTerminated; + this.returnValue = r; + this.deadlyException = deadlyException; + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/ResourcesTest.java b/tests/test-extensions/net/sourceforge/jnlp/ResourcesTest.java new file mode 100644 index 0000000..097ac4f --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/ResourcesTest.java @@ -0,0 +1,389 @@ +/* ResourcesTestl.java +Copyright (C) 2011 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ +package net.sourceforge.jnlp; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.Arrays; +import java.util.List; +import net.sourceforge.jnlp.browsertesting.Browser; +import net.sourceforge.jnlp.browsertesting.BrowserFactory; +import net.sourceforge.jnlp.browsertesting.BrowserTest; +import net.sourceforge.jnlp.browsertesting.Browsers; +import net.sourceforge.jnlp.annotations.NeedsDisplay; +import net.sourceforge.jnlp.browsertesting.browsers.LinuxBrowser; +import net.sourceforge.jnlp.annotations.TestInBrowsers; +import org.junit.Assert; + +import org.junit.Test; + +public class ResourcesTest extends BrowserTest{ + + + @Test + @NeedsDisplay + public void testNonExisitngBrowserWillNotDeadlock() throws Exception { + server.setCurrentBrowser(Browsers.none); + ServerAccess.ProcessResult pr = server.executeBrowser("/simpletest1.jnlp"); + Assert.assertNull(pr.process); + Assert.assertEquals(pr.stderr, ""); + Assert.assertEquals(pr.stdout, ""); + Assert.assertTrue(pr.wasTerminated); + Assert.assertTrue(pr.returnValue < 0); + junit.framework.Assert.assertNotNull(pr.deadlyException); + } + + @Test + public void testUnexistingProcessWillFailRecognizedly() throws Exception { + server.setCurrentBrowser(Browsers.none); + List<String> al=Arrays.asList(new String[] {"definietly_not_Existing_process"}); + ServerAccess.ProcessResult pr = server.executeProcess(al); + Assert.assertNull(pr.process); + Assert.assertEquals(pr.stderr, ""); + Assert.assertEquals(pr.stdout, ""); + Assert.assertTrue(pr.wasTerminated); + Assert.assertTrue(pr.returnValue < 0); + junit.framework.Assert.assertNotNull(pr.deadlyException); + } + + @Test + public void testGetUrlUponThisInstance() throws MalformedURLException{ + URL u1=server.getUrlUponThisInstance("simple.jsp"); + URL u2=server.getUrlUponThisInstance("/simple.jsp"); + Assert.assertEquals(u1, u2); + } + + @Test + @TestInBrowsers(testIn=Browsers.none) + public void testNonExisitngBrowserWillNotCauseMess() throws Exception { + ServerAccess.ProcessResult pr = server.executeBrowser("/simpletest1.jnlp"); + Assert.assertNull(pr.process); + Assert.assertEquals(pr.stderr, ""); + Assert.assertEquals(pr.stdout, ""); + Assert.assertTrue(pr.wasTerminated); + Assert.assertTrue(pr.returnValue < 0); + junit.framework.Assert.assertNotNull(pr.deadlyException); + } + + @Test + public void testBrowsers2() throws Exception { + List<Browser> a = BrowserFactory.getFactory().getAllBrowsers(); + Assert.assertNotNull("returned browsers array must not be null", a); + Assert.assertTrue("at least one browser must be configured", a.size() > 0); + for (Browser b : a) { + testBrowser(b); + } + + } + + @Test + @TestInBrowsers(testIn = Browsers.all) + public void testBrowser3() throws Exception { + testBrowser(server.getCurrentBrowser()); + + + } + + @Test + public void testBrowsers1() throws Exception { + BrowserFactory bf = new BrowserFactory(null); + int expected = 0; + Assert.assertTrue("Created from null there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + bf = new BrowserFactory(""); + expected = 0; + Assert.assertTrue("Created from empty there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + String s = "dsgrdg"; + bf = new BrowserFactory(s); + expected = 0; + Assert.assertTrue("Created from nonsense " + s + " there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = "sgrg/jkik"; + bf = new BrowserFactory(s); + expected = 0; + Assert.assertTrue("Created from nonsense " + s + " there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = Browsers.firefox + "/jkik"; + bf = new BrowserFactory(s); + expected = 0; + Assert.assertTrue("Created from nonsense " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = "sgrg/jkik:sege"; + bf = new BrowserFactory(s); + expected = 0; + Assert.assertTrue("Created from two nonsenses " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = Browsers.firefox.toExec() + ":" + Browsers.firefox; + bf = new BrowserFactory(s); + expected = 2; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = Browsers.firefox.toExec(); + bf = new BrowserFactory(s); + expected = 1; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = "something/somewhere/" + Browsers.firefox.toExec(); + bf = new BrowserFactory(s); + expected = 1; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = "something/somewhere/" + Browsers.firefox.toExec() + ":" + "something/somewhere/" + Browsers.opera.toExec(); + bf = new BrowserFactory(s); + expected = 2; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = "something/somewhere/" + Browsers.firefox.toExec() + ":" + "something/somewhere/" + Browsers.opera.toExec() + ":" + Browsers.chromiumBrowser; + bf = new BrowserFactory(s); + expected = 3; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = Browsers.firefox.toExec() + ":" + "vfdgf" + ":" + Browsers.googleChrome.toExec(); + bf = new BrowserFactory(s); + expected = 2; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = Browsers.firefox.toExec() + ":" + Browsers.chromiumBrowser + ":" + Browsers.googleChrome.toExec() + ":" + Browsers.opera + ":" + Browsers.epiphany + ":" + Browsers.midori; + bf = new BrowserFactory(s); + expected = 6; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + testFullFactory(bf); + + s = "fgfd/" + Browsers.firefox.toExec() + ":" + "/fgfd/" + Browsers.chromiumBrowser + ":" + "fgfd/dfsdf/" + Browsers.googleChrome.toExec() + ":" + "/g/fgfd/" + Browsers.opera + ":" + Browsers.epiphany + ":" + Browsers.midori; + bf = new BrowserFactory(s); + expected = 6; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + testFullFactory(bf); + + s = Browsers.firefox.toExec() + ":" + ":" + Browsers.googleChrome.toExec() + ":" + Browsers.opera; + bf = new BrowserFactory(s); + expected = 3; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = Browsers.firefox.toExec() + ":" + ":" + ":" + Browsers.opera; + bf = new BrowserFactory(s); + expected = 2; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = ":" + ":" + Browsers.googleChrome.toExec() + ":"; + bf = new BrowserFactory(s); + expected = 1; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + s = ":" + Browsers.firefox.toExec() + ":bfgbfg/fddf/" + Browsers.googleChrome.toExec() + ":"; + bf = new BrowserFactory(s); + expected = 2; + Assert.assertTrue("Created from " + s + "there must be " + expected + " browsers in factory. Is" + bf.getAllBrowsers().size(), bf.getAllBrowsers().size() == expected); + + + + + } + + @Test + public void testResourcesExists() throws Exception { + File[] simpleContent = server.getDir().listFiles(new FileFilter() { + + public boolean accept(File file) { + if (!file.isDirectory()) { + return true; + } else { + return false; + } + } + }); + Assert.assertNotNull(simpleContent); + Assert.assertTrue(simpleContent.length > 5); + + for (int i = 0; i < simpleContent.length; i++) { + File file = simpleContent[i]; + ServerAccess.logOutputReprint(file.getName()); + //server port have in fact no usage in converting filename to uri-like-filename. + //But if there is null, instead if some number, then nullpointer exception is thrown (Integer->int). + //So I'm using "real" currently used port, instead of some random value. + URI u = new URI((String) null, (String) null, (String) null, server.getPort(), file.getName(), (String) null, null); + ServerAccess.logOutputReprint(" ("+u.toString()+")"); + String fname = u.toString(); + if (file.getName().toLowerCase().endsWith(".jnlp")) { + String c = server.getResourceAsString("/" + fname); + Assert.assertTrue(c.contains("<")); + Assert.assertTrue(c.contains(">")); + Assert.assertTrue(c.contains("jnlp")); + Assert.assertTrue(c.contains("resources")); + Assert.assertTrue(c.replaceAll("\\s*", "").contains("</jnlp>")); + + } else { + byte[] c = server.getResourceAsBytes("/" + fname).toByteArray(); + Assert.assertEquals(c.length, file.length()); + } + + } + + } + + @Test + @NeedsDisplay + @TestInBrowsers(testIn = Browsers.one) + public void testListeners() throws Exception { + final StringBuilder o1 = new StringBuilder(); + final StringBuilder e1 = new StringBuilder(); + final StringBuilder o2 = new StringBuilder(); + final StringBuilder e2 = new StringBuilder(); + final ContentReaderListener lo = new ContentReaderListener() { + + @Override + public void charReaded(char ch) { + //ServerAccess.logOutputReprint("OO recieved char: "+ch); + o1.append(ch); + } + + @Override + public void lineReaded(String s) { + //ServerAccess.logOutputReprint("OO recieved line: "+s); + o2.append(s).append("\n"); + } + }; + ContentReaderListener le = new ContentReaderListener() { + + @Override + public void charReaded(char ch) { + //ServerAccess.logOutputReprint("EE recieved char: "+ch); + e1.append(ch); + } + + @Override + public void lineReaded(String s) { + //ServerAccess.logOutputReprint("EE recieved line: "+s); + e2.append(s).append("\n"); + } + }; + ServerAccess.ProcessResult pr = server.executeBrowser("/simpletest1.jnlp", le, lo); + server.setCurrentBrowser(BrowserFactory.getFactory().getFirst().getID()); + Assert.assertNotNull(server.getCurrentBrowsers()); + Assert.assertNotNull(server.getCurrentBrowser()); +// ServerAccess.logOutputReprint("total o"); +// ServerAccess.logOutputReprint(pr.stdout); +// ServerAccess.logOutputReprint("total e"); +// ServerAccess.logOutputReprint(pr.stderr); + Assert.assertEquals(pr.stdout, o1.toString()); + Assert.assertEquals(pr.stderr, e1.toString()); + //the last \n is mandatory as las tline is flushed also when proces dies + Assert.assertEquals(pr.stdout.replace("\n", ""), o2.toString().replace("\n", "")); + Assert.assertEquals(pr.stderr.replace("\n", ""), e2.toString().replace("\n", "")); + + } + + private void testFullFactory(BrowserFactory bf) { + Assert.assertEquals(bf.getBrowser(Browsers.chromiumBrowser).getID(), Browsers.chromiumBrowser); + Assert.assertEquals(bf.getBrowser(Browsers.googleChrome).getID(), Browsers.googleChrome); + Assert.assertEquals(bf.getBrowser(Browsers.firefox).getID(), Browsers.firefox); + Assert.assertEquals(bf.getBrowser(Browsers.opera).getID(), Browsers.opera); + Assert.assertEquals(bf.getBrowser(Browsers.epiphany).getID(), Browsers.epiphany); + Assert.assertEquals(bf.getBrowser(Browsers.midori).getID(), Browsers.midori); + } + + private void testBrowser(Browser browser) throws IOException { + File f1 = null; + if (browser.getDefaultPluginExpectedLocation() != null) { + f1 = new File(browser.getDefaultPluginExpectedLocation()); + } + File f2 = null; + if (browser.getUserDefaultPluginExpectedLocation() != null) { + f2 = new File(browser.getUserDefaultPluginExpectedLocation()); + } + if (f1 != null) { + Assert.assertTrue("browser's plugins location should exist " + f1.toString() + " for " + browser.getID().toString(), f1.exists()); + } + if (f2 != null) { + Assert.assertTrue("browser's users-plugins location should exist " + f2.toString() + " for " + browser.getID().toString(), f2.exists()); + } + + File[] ff1 = new File[0]; + if (f1 != null) { + ff1 = f1.listFiles(); + } + + File[] ff2 = new File[0]; + if (f2 != null) { + ff2 = f2.listFiles(); + } + + Assert.assertTrue("at least one of browser's plugins directory should contains at least one file didn't. For " + browser.getID().toString(), ff1.length + ff2.length > 0); + + ff1 = new File[0]; + if (f1 != null) { + ff1 = f1.listFiles(new FileFilter() { + + @Override + public boolean accept(File pathname) { + return (pathname.getName().equals(LinuxBrowser.DEFAULT_PLUGIN_NAME)); + } + }); + } + + ff2 = new File[0]; + if (f2 != null) { + ff2 = f2.listFiles(new FileFilter() { + + @Override + public boolean accept(File pathname) { + return (pathname.getName().equals(LinuxBrowser.DEFAULT_PLUGIN_NAME)); + } + }); + } + + Assert.assertTrue("browser's plugins directories should contains exactly one " + LinuxBrowser.DEFAULT_PLUGIN_NAME + ", but didnt for " + browser.getID().toString(), + ff1.length + ff2.length == 1); + String currentPath = server.getJavawsFile().getParentFile().getParentFile().getAbsolutePath(); + + File[] ff; + if (ff1.length == 1) { + ff = ff1; + } else { + ff = ff2; + } + String s = ServerAccess.getContentOfStream(new FileInputStream(ff[0]), "ASCII"); + Assert.assertTrue("browser's plugins shoud points to" + currentPath + ", but didnt", + s.contains(s)); + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/ServerAccess.java b/tests/test-extensions/net/sourceforge/jnlp/ServerAccess.java new file mode 100644 index 0000000..353d208 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/ServerAccess.java @@ -0,0 +1,828 @@ +/* ServerAccess.java +Copyright (C) 2011 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ +package net.sourceforge.jnlp; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.ServerSocket; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import net.sourceforge.jnlp.browsertesting.Browser; +import net.sourceforge.jnlp.browsertesting.BrowserFactory; +import net.sourceforge.jnlp.browsertesting.Browsers; +import org.junit.Assert; + +/** + * + * This class provides access to virtual server and stuff around. + * It can find unoccupied port, start server, provides its singleton instantiation, lunch parallel instantiations, + * read location of installed (tested javaws) see javaws.build.bin java property, + * location of server www root on file system (see test.server.dir java property), + * stubs for lunching javaws and for locating resources and read resources. + * + * It can also execute processes with timeout (@see PROCESS_TIMEOUT) (used during lunching javaws) + * Some protected apis are exported because public classes in this package are put to be tested by makefile. + * + * There are included test cases which show some basic usages. + * + * + */ +public class ServerAccess { + + public static final long NANO_TIME_DELIMITER=1000000l; + /** + * java property which value containing path to default (makefile by) directory with deployed resources + */ + public static final String TEST_SERVER_DIR = "test.server.dir"; + /** + * java property which value containing path to installed (makefile by) javaws binary + */ + public static final String JAVAWS_BUILD_BIN = "javaws.build.bin"; + /** property to set the different then default browser + */ + public static final String USED_BROWSERS = "used.browsers"; + public static final String DEFAULT_LOCALHOST_NAME = "localhost"; + /** + * server instance singleton + */ + private static ServerLauncher server; + /** + * inner version of engine + */ + private static final String version = "5"; + /** + * timeout to read 'remote' resources + * This can be changed in runtime, but will affect all following tasks + */ + public static int READ_TIMEOUT = 1000; + /** + * timeout in ms to let process to finish, before assassin will kill it. + * This can be changed in runtime, but will affect all following tasks + */ + public static long PROCESS_TIMEOUT = 20 * 1000;//ms + /** + * all terminated processes are stored here. As wee need to 'wait' to termination to be finished. + */ + static Set<Thread> terminated = new HashSet<Thread>(); + /** + * this flag is indicating whether output of executeProcess should be logged. By default true. + */ + public static boolean PROCESS_LOG = true; + public static boolean LOGS_REPRINT = false; + + private Browser currentBrowser; + public static final String UNSET_BROWSER="unset_browser"; + + /** + * main method of this class prints out random free port + * or runs server + * param "port" prints out the port + * nothing or number will run server on random(or on number specified) + * port in -Dtest.server.dir + */ + public static void main(String[] args) throws Exception { + if (args.length > 0 && args[0].equalsIgnoreCase("port")) { + int i = findFreePort(); + System.out.println(i); + System.exit(0); + } else { + int port = 44321; + if (args.length > 0) { + port=new Integer(args[0]); + } + getIndependentInstance(port); + while (true) { + Thread.sleep(1000); + } + + } + } + + /** + * utility method to find random free port + * + * @return - found random free port + * @throws IOException - if socket can't be opened or no free port exists + */ + public static int findFreePort() + throws IOException { + ServerSocket findPortTestingSocket = new ServerSocket(0); + int port = findPortTestingSocket.getLocalPort(); + findPortTestingSocket.close(); + return port; + } + public static final String HEADLES_OPTION="-headless"; + + /** + * we would like to have an singleton instance ASAP + */ + public ServerAccess() { + + getInstance(); + + + } + + /** + * + * @return cached instance. If none, then creates new + */ + public static ServerLauncher getInstance() { + if (server == null) { + server = getIndependentInstance(); + } + return server; + } + + /** + * + * @return new not cached iserver instance on random port, + * useful for testing application loading from different url then base + */ + public static ServerLauncher getIndependentInstance() { + return getIndependentInstance(true); + } + public static ServerLauncher getIndependentInstance(boolean daemon) { + String dir = (System.getProperty(TEST_SERVER_DIR)); + try{ + return getIndependentInstance(dir, findFreePort(),daemon); + }catch (Exception ex){ + throw new RuntimeException(ex); + } + } + + + /** + * + * @return new not cached iserver instance on random port, + * useful for testing application loading from different url then base + */ + + public static ServerLauncher getIndependentInstance(int port) { + return getIndependentInstance(port, true); + } + public static ServerLauncher getIndependentInstance(int port,boolean daemon) { + String dir = (System.getProperty(TEST_SERVER_DIR)); + return getIndependentInstance(dir,port,daemon); + } + + /** + * + * @return new not cached iserver instance on random port upon custom www root directory, + * useful for testing application loading from different url then base + */ + + public static ServerLauncher getIndependentInstance(String dir, int port) { + return getIndependentInstance(dir, port, true); + } + public static ServerLauncher getIndependentInstance(String dir, int port,boolean daemon) { + + + if (dir == null || dir.trim().length() == 0 || !new File(dir).exists() || !new File(dir).isDirectory()) { + throw new RuntimeException("test.server.dir property must be set to valid directory!"); + } + try { + ServerLauncher lServerLuncher = new ServerLauncher(port, new File(dir)); + Thread r=new Thread(lServerLuncher); + r.setDaemon(daemon); + r.start(); + return lServerLuncher; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + } + + /** + * + * @return - value passed inside as javaws binary location. See JAVAWS_BUILD_BIN + */ + public String getJavawsLocation() { + return System.getProperty(JAVAWS_BUILD_BIN); + } + + /** + * + * @return - bianry from where to lunch current browser + */ + public String getBrowserLocation() { + if (this.currentBrowser==null) return UNSET_BROWSER; + return this.currentBrowser.getBin(); + } + + public List<String> getBrowserParams() { + if (this.currentBrowser==null) return null; + List<String> l1=this.currentBrowser.getComaptibilitySwitches(); + List<String> l2=this.currentBrowser.getDefaultSwitches(); + List<String> l= new ArrayList(); + if (l1!=null)l.addAll(l1); + if (l2!=null)l.addAll(l2); + return l; + + } + + public Browsers getCurrentBrowsers() { + if (currentBrowser==null) return null; + return currentBrowser.getID(); + } + public Browser getCurrentBrowser() { + return currentBrowser; + } + + public void setCurrentBrowser(Browsers currentBrowser) { + this.currentBrowser = BrowserFactory.getFactory().getBrowser(currentBrowser); + if (this.currentBrowser == null) { + LoggingBottleneck.getDefaultLoggingBottleneck().setLoggedBrowser(UNSET_BROWSER); + } else { + LoggingBottleneck.getDefaultLoggingBottleneck().setLoggedBrowser(this.currentBrowser.getID().toString()); + } + } + + public void setCurrentBrowser(Browser currentBrowser) { + this.currentBrowser = currentBrowser; + if (this.currentBrowser == null) { + LoggingBottleneck.getDefaultLoggingBottleneck().setLoggedBrowser(UNSET_BROWSER); + } else { + LoggingBottleneck.getDefaultLoggingBottleneck().setLoggedBrowser(this.currentBrowser.getID().toString()); + } + } + + + + /** + * + * @return - value passed inside as javaws binary location as file. See JAVAWS_BUILD_BIN + */ + public File getJavawsFile() { + return new File(System.getProperty(JAVAWS_BUILD_BIN)); + } + + /** + * + * @return port on which is running cached server. If non singleton instance is running, new is created. + */ + public int getPort() { + if (server == null) { + getInstance(); + } + //if (!server.isRunning()) throw new RuntimeException("Server mysteriously died"); + return server.getPort(); + + } + + /** + * + * @return directory upon which is running cached server. If non singleton instance is running, new is created. + */ + public File getDir() { + if (server == null) { + getInstance(); + } + // if (!server.isRunning()) throw new RuntimeException("Server mysteriously died"); + return server.getDir(); + } + + /** + * + * @return url pointing to cached server resource. If non singleton instance is running, new is created. + */ + public URL getUrl(String resource) throws MalformedURLException { + if (server == null) { + getInstance(); + } + //if (!server.isRunning()) throw new RuntimeException("Server mysteriously died"); + return server.getUrl(resource); + } + + /** + * + * @return url pointing to cached server . If non singleton instance is running, new is created. + */ + public URL getUrl() throws MalformedURLException { + return getUrl(""); + + } + + /** + * + * @return whether cached server is alive. If non singleton instance is running, new is created. + */ + public boolean isRunning() { + if (server == null) { + getInstance(); + } + //if (!server.isRunning()) throw new RuntimeException("Server mysteriously died"); + return server.isRunning(); + + } + + /** + * Return resource from cached server + * + * @param resource to be located on cached server + * @return individual bytes of resource + * @throws IOException if connection can't be established or resource does not exist + */ + public ByteArrayOutputStream getResourceAsBytes(String resource) throws IOException { + return getResourceAsBytes(getUrl(resource)); + } + + /** + * Return resource from cached server + * + * @param resource to be located on cached server + * @return string constructed from resource + * @throws IOException if connection can't be established or resource does not exist + */ + public String getResourceAsString(String resource) throws IOException { + return getResourceAsString(getUrl(resource)); + } + + /** + * utility method which can read bytes of any stream + * + * @param input stream to be read + * @return individual bytes of resource + * @throws IOException if connection can't be established or resource does not exist + */ + public static ByteArrayOutputStream getBytesFromStream(InputStream is) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int nRead; + byte[] data = new byte[16384]; + while ((nRead = is.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + buffer.flush(); + return buffer; + } + + /** + * utility method which can read from any stream as one long String + * + * @param input stream + * @return stream as string + * @throws IOException if connection can't be established or resource does not exist + */ + public static String getContentOfStream(InputStream is,String encoding) throws IOException { + try { + BufferedReader br = new BufferedReader(new InputStreamReader(is, encoding)); + StringBuilder sb = new StringBuilder(); + while (true) { + String s = br.readLine(); + if (s == null) { + break; + } + sb.append(s).append("\n"); + + } + return sb.toString(); + } finally { + is.close(); + } + + } + + /** + * utility method which can read from any stream as one long String + * + * @param input stream + * @return stream as string + * @throws IOException if connection can't be established or resource does not exist + */ + public static String getContentOfStream(InputStream is) throws IOException { + return getContentOfStream(is, "UTF-8"); + + } + + /** + * utility method which can read bytes of resource from any url + * + * @param resource to be located on any url + * @return individual bytes of resource + * @throws IOException if connection can't be established or resource does not exist + */ + public static ByteArrayOutputStream getResourceAsBytes(URL u) throws IOException { + HttpURLConnection connection = (HttpURLConnection) u.openConnection(); + connection = (HttpURLConnection) u.openConnection(); + connection.setRequestMethod("GET"); + connection.setDoOutput(true); + connection.setReadTimeout(READ_TIMEOUT); + connection.connect(); + return getBytesFromStream(connection.getInputStream()); + + } + + /** + * utility method which can read string of resource from any url + * + * @param resource to be located on any url + * @return resource as string + * @throws IOException if connection can't be established or resource does not exist + */ + public static String getResourceAsString(URL u) throws IOException { + HttpURLConnection connection = (HttpURLConnection) u.openConnection(); + connection = (HttpURLConnection) u.openConnection(); + connection.setRequestMethod("GET"); + connection.setDoOutput(true); + connection.setReadTimeout(READ_TIMEOUT); + connection.connect(); + return getContentOfStream(connection.getInputStream()); + } + + /** + * helping dummy method to save String as file + * + * @param content + * @param f + * @throws IOException + */ + public static void saveFile(String content, File f) throws IOException { + saveFile(content, f, "utf-8"); + } + public static void saveFile(String content, File f,String encoding) throws IOException { + Writer output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f),encoding)); + output.write(content); + output.flush(); + output.close(); + } + + /** + * wrapping method to executeProcess (eg: javaws -headless http://localhost:port/resource) + * will execute default javaws (@see JAVAWS_BUILD_BIN) upon default url upon cached server (@see SERVER_NAME @see getPort(), @see getInstance()) + * with parameter -headless (no gui, no asking) + * @param resource name of resource + * @return result what left after running this process + * @throws Exception + */ + public ProcessResult executeJavawsHeadless(String resource) throws Exception { + return executeJavawsHeadless(null, resource); + } + public ProcessResult executeJavawsHeadless(String resource,ContentReaderListener stdoutl,ContentReaderListener stderrl) throws Exception { + return executeJavawsHeadless(null, resource,stdoutl,stderrl); + } + + /** + * wrapping method to executeProcess (eg: javaws arg arg -headless http://localhost:port/resource) + * will execute default javaws (@see JAVAWS_BUILD_BIN) upon default url upon cached server (@see SERVER_NAME @see getPort(), @see getInstance()) + * with parameter -headless (no gui, no asking) + * @param resource name of resource + * @param otherargs other arguments to be added to headless one + * @return result what left after running this process + * @throws Exception + */ + public ProcessResult executeJavawsHeadless(List<String> otherargs, String resource) throws Exception { + return executeJavawsHeadless(otherargs, resource,null,null); + } + public ProcessResult executeJavawsHeadless(List<String> otherargs, String resource,ContentReaderListener stdoutl,ContentReaderListener stderrl) throws Exception { + if (otherargs == null) { + otherargs = new ArrayList<String>(1); + } + List<String> headlesList = new ArrayList<String>(otherargs); + headlesList.add(HEADLES_OPTION); + return executeJavaws(headlesList, resource,stdoutl,stderrl); + } + + + /** + * wrapping method to executeProcess (eg: javaws http://localhost:port/resource) + * will execute default javaws (@see JAVAWS_BUILD_BIN) upon default url upon cached server (@see SERVER_NAME @see getPort(), @see getInstance()) + * @param resource name of resource + * @return result what left after running this process + * @throws Exception + */ + public ProcessResult executeJavaws(String resource) throws Exception { + return executeJavaws(null, resource); + } + public ProcessResult executeJavaws(String resource,ContentReaderListener stdoutl,ContentReaderListener stderrl) throws Exception { + return executeJavaws(null, resource,stdoutl,stderrl); + } + public ProcessResult executeBrowser(String resource) throws Exception { + return executeBrowser(getBrowserParams(), resource); + } + public ProcessResult executeBrowser(String resource,ContentReaderListener stdoutl,ContentReaderListener stderrl) throws Exception { + return executeBrowser(getBrowserParams(), resource,stderrl,stdoutl); + } + + /** + * wrapping method to executeProcess (eg: javaws arg arg http://localhost:port/resource) + * will execute default javaws (@see JAVAWS_BUILD_BIN) upon default url upon cached server (@see SERVER_NAME @see getPort(), @see getInstance())) + * @param resource name of resource + * @param otherargs other arguments to be added + * @return result what left after running this process + * @throws Exception + */ + public ProcessResult executeJavaws(List<String> otherargs, String resource) throws Exception { + return executeProcessUponURL(getJavawsLocation(), otherargs, getUrlUponThisInstance(resource)); + } + public ProcessResult executeJavaws(List<String> otherargs, String resource,ContentReaderListener stdoutl,ContentReaderListener stderrl) throws Exception { + return executeProcessUponURL(getJavawsLocation(), otherargs, getUrlUponThisInstance(resource),stdoutl,stderrl); + } + + public ProcessResult executeBrowser(List<String> otherargs, String resource) throws Exception { + return executeProcessUponURL(getBrowserLocation(), otherargs, getUrlUponThisInstance(resource)); + } + public ProcessResult executeBrowser(List<String> otherargs, String resource,ContentReaderListener stdoutl,ContentReaderListener stderrl) throws Exception { + return executeProcessUponURL(getBrowserLocation(), otherargs, getUrlUponThisInstance(resource),stdoutl,stderrl); + } + + public ProcessResult executeBrowser(Browser b,List<String> otherargs, String resource) throws Exception { + return executeProcessUponURL(b.getBin(), otherargs, getUrlUponThisInstance(resource)); + } + public ProcessResult executeBrowser(Browser b,List<String> otherargs, String resource,ContentReaderListener stdoutl,ContentReaderListener stderrl) throws Exception { + return executeProcessUponURL(b.getBin(), otherargs, getUrlUponThisInstance(resource),stdoutl,stderrl); + } + + /** + * Ctreate resource on http, on 'localhost' on port on which this instance is running + * @param resource + * @return + * @throws MalformedURLException + */ + public URL getUrlUponThisInstance(String resource) throws MalformedURLException { + if (!resource.startsWith("/")) { + resource = "/" + resource; + } + return new URL("http", server.getServerName(), getPort(), resource); + } + + /** + * wrapping method to executeProcess (eg: javaws arg arg arg url) + * will execute default javaws (@see JAVAWS_BUILD_BIN) upon any server + * @param u url of resource upon any server + * @param javaws arguments + * @return result what left after running this process + * @throws Exception + */ + public ProcessResult executeJavawsUponUrl(List<String> otherargs, URL u) throws Exception { + return executeProcessUponURL(getJavawsLocation(), otherargs, u); + } + public ProcessResult executeJavawsUponUrl(List<String> otherargs, URL u,ContentReaderListener stdoutl,ContentReaderListener stderrl) throws Exception { + return executeProcessUponURL(getJavawsLocation(), otherargs, u,stdoutl,stderrl); + } + + /** + * wrapping utility method to executeProcess (eg: any_binary arg arg arg url) + * + * will execute any process upon url upon any server + * @param u url of resource upon any server + * @param javaws arguments + * @return result what left after running this process + * @throws Exception + */ + public static ProcessResult executeProcessUponURL(String toBeExecuted, List<String> otherargs, URL u) throws Exception { + return executeProcessUponURL(toBeExecuted, otherargs, u,null,null); + } + + public static ProcessResult executeProcessUponURL(String toBeExecuted, List<String> otherargs, URL u,ContentReaderListener stdoutl,ContentReaderListener stderrl) throws Exception { + Assert.assertNotNull(u); + Assert.assertNotNull(toBeExecuted); + Assert.assertTrue(toBeExecuted.trim().length() > 1); + if (otherargs == null) { + otherargs = new ArrayList<String>(1); + } + List<String> urledArgs = new ArrayList<String>(otherargs); + urledArgs.add(0, toBeExecuted); + urledArgs.add(u.toString()); + return executeProcess(urledArgs, stdoutl, stderrl); + } + + public static ProcessResult executeProcess(final List<String> args) throws Exception { + return executeProcess(args, null); + } + public static ProcessResult executeProcess(final List<String> args,ContentReaderListener stdoutl,ContentReaderListener stderrl) throws Exception { + return executeProcess(args, null,stdoutl,stderrl); + } + /** + * utility method to lunch process, get its stdout/stderr, its return value and to kill it if running to long (@see PROCESS_TIMEOUT) + * + * + * Small bacground: + * This method creates thread inside which exec will be executed. Then creates assassin thread with given timeout to kill the previously created thread if necessary. + * Starts assassin thread, starts process thread. Wait until process is running, then starts content readers. + * Closes input of process. + * Wait until process is running (no matter if it terminate itself (correctly or badly), or is terminated by its assassin. + * Construct result from readed stdout, stderr, process return value, assassin successfully + * + * @param args binary with args to be executed + * @param dir optional, directory where this process will run + * @return what left from process - process itself, its stdout, stderr and return value and whether it was terminated by assassin. + * @throws Exception + */ + public static ProcessResult executeProcess(final List<String> args,File dir) throws Exception { + return executeProcess(args, dir, null, null); + } + + private static String createConnectionMessage(ThreadedProcess t) { + return "Connecting " + t.getCommandLine(); + } + + /** + * Proceed message s to logging with request to reprint to System.err + * @param s + */ + public static void logErrorReprint(String s) { + log(s, false, true); + } + + /** + * Proceed message s to logging with request to reprint to System.out + * @param s + */ + public static void logOutputReprint(String s) { + log(s, true, false); + } + + /** + * Proceed message s to logging withhout request to reprint + * @param s + */ + public static void logNoReprint(String s) { + log(s, false, false); + } + + private static void log(String message, boolean printToOut, boolean printToErr) { + String idded; + StackTraceElement ste = getTestMethod(); + String fullId = ste.getClassName() + "." + ste.getMethodName(); + fullId = LoggingBottleneck.getDefaultLoggingBottleneck().modifyMethodWithForBrowser(ste.getMethodName(), ste.getClassName()); + if (message.contains("\n")) { + idded = fullId + ": \n" + message + "\n" + fullId + " ---"; + } else { + idded = fullId + ": " + message; + + } + if (LOGS_REPRINT) { + if (printToOut) { + System.out.println(idded); + } + if (printToErr) { + System.err.println(idded); + } + } + LoggingBottleneck.getDefaultLoggingBottleneck().logIntoPlaintextLog(idded, printToOut,printToErr); + LoggingBottleneck.getDefaultLoggingBottleneck().addToXmlLog(message,printToOut,printToErr,ste); + } + + public static void logException(Throwable t){ + logException(t, true); + } + public static void logException(Throwable t, boolean print){ + try{ + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + t.printStackTrace(pw); + log(sw.toString(), false, print); + pw.close(); + sw.close(); + }catch(Exception ex){ + throw new RuntimeException(ex); + } + } + + private static StackTraceElement getTestMethod() { + return getTestMethod(Thread.currentThread().getStackTrace()); + } + + private static StackTraceElement getTestMethod(StackTraceElement[] stack) { + //0 is always thread + //1 is net.sourceforge.jnlp.ServerAccess + StackTraceElement result = stack[1]; + String baseClass = stack[1].getClassName(); + int i = 2; + for (; i < stack.length; i++) { + result = stack[i];//at least moving up + if(stack[i].getClassName().contains("$")){ + continue; + } + if (!baseClass.equals(stack[i].getClassName())) { + break; + } + } + //if nothing left in stack then we have been in ServerAccess already + //so the target method is the highest form it and better to return it + //rather then die to ArrayOutOfBounds + if(i >= stack.length){ + return result; + } + //now we are out of net.sourceforge.jnlp.ServerAccess + //method we need (the test) is highest from following class + baseClass = stack[i].getClassName(); + for (; i < stack.length; i++) { + if(stack[i].getClassName().contains("$")){ + continue; + } + if (!baseClass.equals(stack[i].getClassName())) { + break; + } + result = stack[i]; + } + + return result; + } + + public static ProcessResult executeProcess(final List<String> args, File dir, ContentReaderListener stdoutl, ContentReaderListener stderrl) throws Exception { + ThreadedProcess t = new ThreadedProcess(args, dir); + if (PROCESS_LOG) { + String connectionMesaage = createConnectionMessage(t); + log(connectionMesaage, true, true); + } + ProcessAssasin pa = new ProcessAssasin(t, PROCESS_TIMEOUT); + pa.start(); + t.start(); + while (t.getP() == null && t.deadlyException == null) { + Thread.sleep(100); + } + if (t.deadlyException != null) { + pa.setCanRun(false); + return new ProcessResult("", "", null, true, Integer.MIN_VALUE, t.deadlyException); + } + ContentReader crs = new ContentReader(t.getP().getInputStream(),stdoutl); + ContentReader cre = new ContentReader(t.getP().getErrorStream(),stderrl); + + OutputStream out = t.getP().getOutputStream(); + if (out != null) { + out.close(); + } + + new Thread(crs).start(); + new Thread(cre).start(); + while (t.isRunning()) { + Thread.sleep(100); + } + + while (!t.isDestoyed()) { + Thread.sleep(100); + } + pa.setCanRun(false); + // ServerAccess.logOutputReprint(t.getP().exitValue()); when process is killed, this throws exception + + ProcessResult pr=new ProcessResult(crs.getContent(), cre.getContent(), t.getP(), pa.wasTerminated(), t.getExitCode(), null); + if (PROCESS_LOG) { + log(pr.stdout, true, false); + log(pr.stderr, false, true); + } + return pr; + } + + /** + * this is temprary solution until refactoring is fully done + * Use net.sourceforge.jnlp.ProcessResult instead + */ + @Deprecated + public static class ProcessResult extends net.sourceforge.jnlp.ProcessResult { + + public ProcessResult(String stdout, String stderr, Process process, boolean wasTerminated, Integer r, Throwable deadlyException) { + super(stdout, stderr, process, wasTerminated, r, deadlyException); + } + } + } diff --git a/tests/test-extensions/net/sourceforge/jnlp/ServerLauncher.java b/tests/test-extensions/net/sourceforge/jnlp/ServerLauncher.java new file mode 100644 index 0000000..92634cc --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/ServerLauncher.java @@ -0,0 +1,120 @@ +/* ServerLauncher.java +Copyright (C) 2011,2012 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package net.sourceforge.jnlp; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.ServerSocket; +import java.net.URL; + +/** + * wrapper around tiny http server to separate lunch configurations and servers. + * to allow terminations and stuff around. + */ +public class ServerLauncher implements Runnable { + + /** + * default url name part. + * This can be changed in runtime, but will affect all following tasks upon those server + */ + private String serverName = ServerAccess.DEFAULT_LOCALHOST_NAME; + private boolean running; + private final Integer port; + private final File dir; + + public String getServerName() { + return serverName; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } + + public ServerLauncher(Integer port, File dir) { + this.port = port; + this.dir = dir; + System.err.println("port: " + port); + System.err.println("dir: " + dir); + } + + public boolean isRunning() { + return running; + } + + public Integer getPort() { + return port; + } + + public File getDir() { + return dir; + } + + public ServerLauncher(File dir) { + this(8181, dir); + } + + public ServerLauncher(Integer port) { + this(port, new File(System.getProperty("user.dir"))); + } + + public ServerLauncher() { + this(8181, new File(System.getProperty("user.dir"))); + } + + public void run() { + running = true; + try { + ServerSocket s = new ServerSocket(port); + while (running) { + new TinyHttpdImpl(s.accept(), dir, port); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + running = false; + } + } + + public URL getUrl(String resource) throws MalformedURLException { + return new URL("http", getServerName(), getPort(), resource); + } + + public URL getUrl() throws MalformedURLException { + return getUrl(""); + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/TestsLogs.java b/tests/test-extensions/net/sourceforge/jnlp/TestsLogs.java new file mode 100644 index 0000000..3277dfe --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/TestsLogs.java @@ -0,0 +1,85 @@ +/* TestsLogs.java +Copyright (C) 2011,2012 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package net.sourceforge.jnlp; + +import java.util.LinkedList; +import java.util.List; + +class TestsLogs { + + public final List<LogItem> outs = new LinkedList<LogItem>(); + public final List<LogItem> errs = new LinkedList<LogItem>(); + public final List<LogItem> all = new LinkedList<LogItem>(); + private static final String LOG_ELEMENT = "log"; + private static final String LOG_ID_ATTRIBUTE = "id"; + + synchronized void add(boolean err, boolean out, String text) { + if (text == null) { + text = "null"; + } + LogItem li = new LogItem(text); + if (out) { + outs.add(li); + } + if (err) { + errs.add(li); + } + all.add(li); + + } + + @Override + public String toString() { + StringBuilder sb = listToStringBuilder(outs, "out"); + sb.append(listToStringBuilder(errs, "err")); + sb.append(listToStringBuilder(all, "all")); + return sb.toString(); + } + + private StringBuilder listToStringBuilder(List<LogItem> l, String id) { + StringBuilder sb = new StringBuilder(); + sb.append("<" + LOG_ELEMENT + " " + LOG_ID_ATTRIBUTE + "=\"").append(id).append("\">\n"); + int i = 0; + for (LogItem logItem : l) { + i++; + sb.append(logItem.toStringBuilder(i)); + } + sb.append("</" + LOG_ELEMENT + ">\n"); + return sb; + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/ThreadedProcess.java b/tests/test-extensions/net/sourceforge/jnlp/ThreadedProcess.java new file mode 100644 index 0000000..c37d842 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/ThreadedProcess.java @@ -0,0 +1,140 @@ +/* ThreadedProcess.java +Copyright (C) 2011,2012 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package net.sourceforge.jnlp; + +import java.io.File; +import java.util.List; + +/** + * + * wrapper around Runtime.getRuntime().exec(...) which ensures that process is run inside its own, by us controlled, thread. + * Process builder caused some unexpected and weird behavior :/ + */ +class ThreadedProcess extends Thread { + + Process p = null; + List<String> args; + Integer exitCode; + Boolean running; + File dir; + Throwable deadlyException = null; + /* + * before removing this "useless" variable + * check DeadLockTestTest.testDeadLockTestTerminated2 + */ + private boolean destoyed = false; + + public boolean isDestoyed() { + return destoyed; + } + + public void setDestoyed(boolean destoyed) { + this.destoyed = destoyed; + } + + public Boolean isRunning() { + return running; + } + + public Integer getExitCode() { + return exitCode; + } + + public ThreadedProcess(List<String> args) { + this.args = args; + } + + public ThreadedProcess(List<String> args, File dir) { + this.args = args; + this.dir = dir; + } + + public String getCommandLine() { + String commandLine = "unknown command"; + try { + if (args != null && args.size() > 0) { + commandLine = ""; + for (String string : args) { + commandLine = commandLine + " " + string; + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + return commandLine; + } + } + + public Process getP() { + return p; + } + + @Override + public void run() { + try { + running = true; + Runtime r = Runtime.getRuntime(); + if (dir == null) { + p = r.exec(args.toArray(new String[0])); + } else { + p = r.exec(args.toArray(new String[0]), new String[0], dir); + } + try { + exitCode = p.waitFor(); + Thread.sleep(500); //this is giving to fast done proecesses's e/o readers time to read all. I would like to know better solution :-/ + } finally { + destoyed = true; + } + } catch (Exception ex) { + if (ex instanceof InterruptedException) { + //add to the set of terminated threaded processes + deadlyException = ex; + ServerAccess.logException(deadlyException, false); + ServerAccess.terminated.add(this); + } else { + //happens when non-existing process is launched, is causing p null! + ServerAccess.terminated.add(this); + deadlyException = ex; + ServerAccess.logException(deadlyException, false); + throw new RuntimeException(ex); + } + } finally { + running = false; + } + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/TinyHttpdImpl.java b/tests/test-extensions/net/sourceforge/jnlp/TinyHttpdImpl.java new file mode 100644 index 0000000..34870ab --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/TinyHttpdImpl.java @@ -0,0 +1,174 @@ +/* TinyHttpdImpl.java +Copyright (C) 2011,2012 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package net.sourceforge.jnlp; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.net.Socket; +import java.net.SocketException; +import java.net.URLDecoder; +import java.util.StringTokenizer; + +/** + * based on http://www.mcwalter.org/technology/java/httpd/tiny/index.html + * Very small implementation of http return headers for our served resources + * Originally Licenced under GPLv2.0 + * + * When resource starts with XslowX prefix, then resouce (without XslowX) + * is returned, but its delivery is delayed + */ +class TinyHttpdImpl extends Thread { + + Socket c; + private final File dir; + private final int port; + private boolean canRun = true; + private static final String XSX = "/XslowX"; + + public TinyHttpdImpl(Socket s, File f, int port) { + c = s; + this.dir = f; + this.port = port; + start(); + } + + public void setCanRun(boolean canRun) { + this.canRun = canRun; + } + + public int getPort() { + return port; + } + + @Override + public void run() { + try { + BufferedReader i = new BufferedReader(new InputStreamReader(c.getInputStream())); + DataOutputStream o = new DataOutputStream(c.getOutputStream()); + try { + while (canRun) { + String s = i.readLine(); + if (s.length() < 1) { + break; + } + if (s.startsWith("GET")) { + StringTokenizer t = new StringTokenizer(s, " "); + t.nextToken(); + String op = t.nextToken(); + String p = op; + if (p.startsWith(XSX)) { + p = p.replace(XSX, "/"); + } + ServerAccess.logNoReprint("Getting: " + p); + p = URLDecoder.decode(p, "UTF-8"); + ServerAccess.logNoReprint("Serving: " + p); + p = (".".concat((p.endsWith("/")) ? p.concat("index.html") : p)).replace('/', File.separatorChar); + File pp = new File(dir, p); + int l = (int) pp.length(); + byte[] b = new byte[l]; + FileInputStream f = new FileInputStream(pp); + f.read(b); + String content = ""; + String ct = "Content-Type: "; + if (p.toLowerCase().endsWith(".jnlp")) { + content = ct + "application/x-java-jnlp-file\n"; + } else if (p.toLowerCase().endsWith(".html")) { + content = ct + "text/html\n"; + } else if (p.toLowerCase().endsWith(".jar")) { + content = ct + "application/x-jar\n"; + } + o.writeBytes("HTTP/1.0 200 OK\nConten" + "t-Length:" + l + "\n" + content + "\n"); + if (op.startsWith(XSX)) { + byte[][] bb = splitArray(b, 10); + for (int j = 0; j < bb.length; j++) { + Thread.sleep(2000); + byte[] bs = bb[j]; + o.write(bs, 0, bs.length); + } + } else { + o.write(b, 0, l); + } + } + } + } catch (SocketException e) { + ServerAccess.logException(e, false); + } catch (Exception e) { + o.writeBytes("HTTP/1.0 404 ERROR\n\n\n"); + ServerAccess.logException(e, false); + } + o.close(); + } catch (Exception e) { + ServerAccess.logException(e, false); + } + } + + /** + * This function splits input array to severasl pieces + * from byte[length] splitt to n pieces s is retrunrd byte[n][length/n], except + * last piece which contains length%n + * + * @param input - array to be splitted + * @param pieces - to how many pieces it should be broken + * @return inidividual pices of original array, which concatet again givs original array + */ + public static byte[][] splitArray(byte[] input, int pieces) { + int rest = input.length; + int rowLength = rest / pieces; + if (rest % pieces > 0) { + rowLength++; + } + if (pieces * rowLength >= rest + rowLength) { + pieces--; + } + int i = 0, j = 0; + byte[][] array = new byte[pieces][]; + array[0] = new byte[rowLength]; + for (byte b : input) { + if (i >= rowLength) { + i = 0; + array[++j] = new byte[Math.min(rowLength, rest)]; + } + array[j][i++] = b; + rest--; + } + return array; + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/annotations/Bug.java b/tests/test-extensions/net/sourceforge/jnlp/annotations/Bug.java new file mode 100644 index 0000000..ac157d9 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/annotations/Bug.java @@ -0,0 +1,32 @@ +package net.sourceforge.jnlp.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * When declare for suite class or for Test-marked method, + * should be interpreted by report generating tool to links. + * Known shortcuts are + * SX - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=X + * PRX - http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=X + * RHX - https://bugzilla.redhat.com/show_bug.cgi?id=X + * DX - http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=X + * GX - http://bugs.gentoo.org/show_bug.cgi?id=X + * CAX - http://server.complang.tuwien.ac.at/cgi-bin/bugzilla/show_bug.cgi?id=X + * LPX - https://bugs.launchpad.net/bugs/X + * + * http://mail.openjdk.java.net/pipermail/distro-pkg-dev/ + * and http://mail.openjdk.java.net/pipermail/ are proceed differently + * You just put eg @Bug(id="RH12345",id="http:/my.bukpage.com/terribleNew") + * and RH12345 will be transalated as + * <a href="https://bugzilla.redhat.com/show_bug.cgi?id=123456">123456<a> or + * similar, the url will be inclueded as is. Both added to proper tests or suites + * + */ +@Target({ElementType.METHOD,ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Bug { + public String[] id(); +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/annotations/KnownToFail.java b/tests/test-extensions/net/sourceforge/jnlp/annotations/KnownToFail.java new file mode 100644 index 0000000..e7c2464 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/annotations/KnownToFail.java @@ -0,0 +1,24 @@ +package net.sourceforge.jnlp.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * <p> + * This annotation marks a test as a known failure (as opposed to a + * regression). A test that is a known failure will not hold of a release, + * nor should developers hold off a fix if they run the unit tests and a + * test marked as a known failure fails. + * </p><p> + * This annotation is meant for adding tests for bugs before the fix is + * implemented. + * </p> + */ + +@Target({ElementType.METHOD,ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface KnownToFail { + +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/annotations/NeedsDisplay.java b/tests/test-extensions/net/sourceforge/jnlp/annotations/NeedsDisplay.java new file mode 100644 index 0000000..e8b9d49 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/annotations/NeedsDisplay.java @@ -0,0 +1,18 @@ + +package net.sourceforge.jnlp.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation should be declared for each test which requires DISPALY defined. + * If no display is defined, then those test will not be run + * + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface NeedsDisplay { + +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/annotations/TestInBrowsers.java b/tests/test-extensions/net/sourceforge/jnlp/annotations/TestInBrowsers.java new file mode 100644 index 0000000..b4ea2a3 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/annotations/TestInBrowsers.java @@ -0,0 +1,18 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package net.sourceforge.jnlp.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import net.sourceforge.jnlp.browsertesting.Browsers; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface TestInBrowsers { + public Browsers[] testIn(); +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/Browser.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/Browser.java new file mode 100644 index 0000000..81db960 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/Browser.java @@ -0,0 +1,19 @@ +package net.sourceforge.jnlp.browsertesting; + +import java.util.List; + +/** + * interface which represents individual browsers + */ +public interface Browser { + public String getDefaultBin(); + public String getDefaultPluginExpectedLocation(); + public String getBin(); + //public void setBin(String bin); + public String getUserDefaultPluginExpectedLocation(); + public Browsers getID(); + public List<String> getComaptibilitySwitches(); + public List<String> getDefaultSwitches(); + + +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/BrowserFactory.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/BrowserFactory.java new file mode 100644 index 0000000..7171afc --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/BrowserFactory.java @@ -0,0 +1,189 @@ +package net.sourceforge.jnlp.browsertesting; + +import net.sourceforge.jnlp.annotations.TestInBrowsers; +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import net.sourceforge.jnlp.ServerAccess; +import net.sourceforge.jnlp.browsertesting.browsers.Chrome; +import net.sourceforge.jnlp.browsertesting.browsers.Chromium; +import net.sourceforge.jnlp.browsertesting.browsers.Epiphany; +import net.sourceforge.jnlp.browsertesting.browsers.Firefox; +import net.sourceforge.jnlp.browsertesting.browsers.Midory; +import net.sourceforge.jnlp.browsertesting.browsers.Opera; + +public class BrowserFactory { + + private static final BrowserFactory factory = new BrowserFactory(System.getProperty(ServerAccess.USED_BROWSERS)); + private List<Browser> configuredBrowsers; + Random oneGenerator = new Random(); + + public static BrowserFactory getFactory() { + return factory; + } + + /** + * This is public just for testing purposes! + */ + public BrowserFactory(String browsers) { + if (browsers == null) { + configuredBrowsers = new ArrayList<Browser>(0); + } else { + String[] s = browsers.split(File.pathSeparator); + configuredBrowsers = new ArrayList<Browser>(s.length); + for (int i = 0; i < s.length; i++) { + String string = s[i]; + String[] p = string.split("/"); + if (p.length > 1) { + string = p[p.length - 1]; + } + if (string.equals(Browsers.chromiumBrowser.toString())) { + configuredBrowsers.add(new Chromium(s[i])); + } + if (string.equals(Browsers.googleChrome.toString())) { + configuredBrowsers.add(new Chrome(s[i])); + } + if (string.equals(Browsers.opera.toString())) { + configuredBrowsers.add(new Opera(s[i])); + } + if (string.equals(Browsers.firefox.toString())) { + configuredBrowsers.add(new Firefox(s[i])); + } + if (string.equals(Browsers.epiphany.toString())) { + configuredBrowsers.add(new Epiphany(s[i])); + } + if (string.equals(Browsers.midori.toString())) { + configuredBrowsers.add(new Midory(s[i])); + } + } + } + + } + + public Browser getBrowser(Browsers id) { + for (int i = 0; i < configuredBrowsers.size(); i++) { + Browser browser = configuredBrowsers.get(i); + if (browser.getID() == id) { + return browser; + } + + } + return null; + + } + + public Browser getFirst() { + for (int i = 0; i < configuredBrowsers.size(); i++) { + Browser browser = configuredBrowsers.get(i); + return browser; + + } + return null; + + } + + public Browser getRandom() { + if (configuredBrowsers.isEmpty()){ + return null; + } + return configuredBrowsers.get(oneGenerator.nextInt(configuredBrowsers.size())); + } + + public List<Browser> getAllBrowsers() { + return Collections.unmodifiableList(configuredBrowsers); + } + + public List<Browsers> getBrowsers(TestInBrowsers tib) { + return getBrowsers(tib.testIn()); + } + public List<Browsers> getBrowsers(Browsers[] testIn) { + List<Browser> q = translateAnnotationSilently(testIn); + if (q==null || q.isEmpty()){ + List<Browsers> qq = new ArrayList<Browsers>(0); + qq.add(Browsers.none); + return qq; + } + List<Browsers> qq = new ArrayList<Browsers>(q.size()); + for (Browser browser : q) { + qq.add(browser.getID()); + } + return qq; + + } + /** + * + * @param testIn Bbrowsers which should be transformed to list of Browser + * @return all matching browser, if browser do not exists, this is ignored and run is silently continued + */ + public List<Browser> translateAnnotationSilently(Browsers[] testIn) { + if (testIn==null) { + return null; + } + List<Browser> r = new ArrayList<Browser>(configuredBrowsers.size()); + for (Browsers b : testIn) { + if (b == Browsers.all) { + if (getAllBrowsers().isEmpty()) { + ServerAccess.logErrorReprint("You try to add all browsers, but there is none"); + } else { + r.addAll(getAllBrowsers()); + } + } else if (b == Browsers.one) { + Browser bb = getRandom(); + if (bb == null) { + ServerAccess.logErrorReprint("You try to add random browser, but there is none"); + } else { + r.add(bb); + } + } else { + Browser bb = getBrowser(b); + if (bb == null) { + ServerAccess.logErrorReprint("You try to add " + b.toString() + " browser, but it do not exists"); + } else { + r.add(bb); + } + + } + } + + return r; + + } + + /** + * + * @param tib + * @return all matching browser, if browser do not exists, exception is thrown + */ + public List<Browser> translateAnnotationLaudly(TestInBrowsers tib) { + return translateAnnotationLaudly(tib.testIn()); + } + public List<Browser> translateAnnotationLaudly(Browsers[] testIn) { + List<Browser> r = new ArrayList<Browser>(configuredBrowsers.size()); + for (Browsers b :testIn) { + if (b == Browsers.all) { + if (getAllBrowsers().isEmpty()) { + throw new IllegalStateException("You try to add all browsers, but there is none"); + } + r.addAll(getAllBrowsers()); + } else if (b == Browsers.one) { + Browser bb = getRandom(); + if (bb == null) { + throw new IllegalStateException("You try to add random browser, but there is none"); + } + r.add(bb); + } else { + Browser bb = getBrowser(b); + if (bb == null) { + throw new IllegalStateException("You try to add " + b.toString() + " browser, but it do not exists"); + } + r.add(bb); + + } + } + + return r; + + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/BrowserTest.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/BrowserTest.java new file mode 100644 index 0000000..232b63a --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/BrowserTest.java @@ -0,0 +1,23 @@ +package net.sourceforge.jnlp.browsertesting; + +import net.sourceforge.jnlp.ServerAccess; +import org.junit.runner.RunWith; + + +@RunWith(value = BrowserTestRunner.class) +public abstract class BrowserTest { + + public static Browsers browser=null; + public static final ServerAccess server = new ServerAccess(); + + public static void setBrowser(Browsers b) { + browser = b; + server.setCurrentBrowser(browser); + } + + public static Browsers getBrowser() { + return browser; + } + + +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/BrowserTestRunner.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/BrowserTestRunner.java new file mode 100644 index 0000000..36350e8 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/BrowserTestRunner.java @@ -0,0 +1,148 @@ +package net.sourceforge.jnlp.browsertesting; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +import net.sourceforge.jnlp.annotations.TestInBrowsers; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import net.sourceforge.jnlp.ServerAccess; +import org.junit.Ignore; +import org.junit.internal.AssumptionViolatedException; +import org.junit.internal.runners.model.EachTestNotifier; +import org.junit.runner.Description; +import org.junit.runner.notification.RunNotifier; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; +import org.junit.runners.model.Statement; + +public class BrowserTestRunner extends BlockJUnit4ClassRunner { + + public BrowserTestRunner(java.lang.Class<?> testClass) throws InitializationError { + super(testClass); + } + + @Override + protected void runChild(FrameworkMethod method, RunNotifier notifier) { + Method mm = method.getMethod(); + TestInBrowsers tib = mm.getAnnotation(TestInBrowsers.class); + injectBrowserCatched(method, Browsers.none); + boolean browserIgnoration = false; + if (tib != null) { + try { + List<Browsers> testableBrowsers = BrowserFactory.getFactory().getBrowsers(tib); + String mbr = System.getProperty("modified.browsers.run"); + if (mbr != null) { + if (mbr.equalsIgnoreCase("all")) { + if (!isBrowsersNoneSet(tib)) { + testableBrowsers = BrowserFactory.getFactory().getBrowsers(new Browsers[]{Browsers.all}); + } + } else if (mbr.equalsIgnoreCase("one")) { + //this complication here is for case like + // namely enumerated concrete browsers, so we want to pick up + // random one from those already enumerated + if (isBrowsersNoneSet(tib)) { + testableBrowsers = Arrays.asList(new Browsers[]{testableBrowsers.get(new Random().nextInt(testableBrowsers.size()))}); + } + } else if (mbr.equalsIgnoreCase("ignore")) { + testableBrowsers = BrowserFactory.getFactory().getBrowsers(new Browsers[]{Browsers.none}); + browserIgnoration = true; + } else { + ServerAccess.logErrorReprint("unrecognized value of modified.browsers.run - " + mbr); + } + } + for (Browsers browser : testableBrowsers) { + try { + injcetBrowser(method, browser); + runChildX(method, notifier, browser, browserIgnoration); + } catch (Exception ex) { + //throw new RuntimeException("unabled to inject browser", ex); + ServerAccess.logException(ex, true); + } + } + } finally { + injectBrowserCatched(method, Browsers.none); + } + } else { + runChildX(method, notifier, null, false); + } + } + + private boolean isBrowsersNoneSet(TestInBrowsers tib) { + if (tib.testIn().length == 1 && tib.testIn()[0] == Browsers.none) { + return true; + } + return false; + } + + private void injectBrowserCatched(FrameworkMethod method, Browsers browser) { + try { + injcetBrowser(method, browser); + } catch (Exception ex) { + //throw new RuntimeException("unabled to inject browser", ex); + ServerAccess.logException(ex, true); + } + } + + private void injcetBrowser(FrameworkMethod method, Browsers browser) throws IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { + Method ff = method.getMethod().getDeclaringClass().getMethod("setBrowser", Browsers.class); + ff.invoke(null, browser); + } + + protected void runChildX(final FrameworkMethod method, RunNotifier notifier, Browsers browser, boolean browserIgnoration) { + Description description = describeChild(method, browser); + if (method.getAnnotation(Ignore.class) != null) { + notifier.fireTestIgnored(description); + } else { + try { + runLeaf(methodBlock(method), description, notifier, browserIgnoration); +// ServerAccess.logOutputReprint("trying leaf"); +// Method m = this.getClass().getMethod("runLeaf", Statement.class, Description.class, RunNotifier.class); +// m.setAccessible(true); +// m.invoke(this, methodBlock(method), description, notifier); +// ServerAccess.logOutputReprint("leaf invoked"); + } catch (Exception ex) { + //throw new RuntimeException("unabled to lunch test on leaf", ex); + ServerAccess.logException(ex, true); + } + } + } + + /** + * Runs a {@link Statement} that represents a leaf (aka atomic) test. + */ + protected final void runLeaf(Statement statement, Description description, + RunNotifier notifier, boolean ignore) { + EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description); + eachNotifier.fireTestStarted(); + if (ignore) { + eachNotifier.fireTestIgnored(); + return; + } + try { + statement.evaluate(); + } catch (AssumptionViolatedException e) { + eachNotifier.addFailedAssumption(e); + } catch (Throwable e) { + eachNotifier.addFailure(e); + } finally { + eachNotifier.fireTestFinished(); + } + } + + protected Description describeChild(FrameworkMethod method, Browsers browser) { + if (browser == null) { + return super.describeChild(method); + } else { + try { + return Description.createTestDescription(getTestClass().getJavaClass(), + testName(method) + " - " + browser.toString(), method.getAnnotations()); + } catch (Exception ex) { + ServerAccess.logException(ex, true); + return super.describeChild(method); + } + } + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/Browsers.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/Browsers.java new file mode 100644 index 0000000..8d85241 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/Browsers.java @@ -0,0 +1,46 @@ +package net.sourceforge.jnlp.browsertesting; + +/** + * When all represent all configured browser, one represens one random + * (the first found) configured browser. Each other represents inidivdual browsers + * + */ +public enum Browsers { + + none, all, one, opera, googleChrome, chromiumBrowser, firefox, midori,epiphany; + + public String toExec() { + switch (this) { + case opera: + return "opera"; + case googleChrome: + return "google-chrome"; + case chromiumBrowser: + return "chromium-browser"; + case firefox: + return "firefox"; + case midori: + return "midori"; + case epiphany: + return "epiphany"; + default: + return null; + + } + } + + @Override + public String toString() { + if (toExec()!=null) return toExec(); + switch (this) { + case all: + return "all"; + case one: + return "one"; + case none: + return "unset_browser"; + default: return "unknown"; + + } + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Chrome.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Chrome.java new file mode 100644 index 0000000..2668d65 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Chrome.java @@ -0,0 +1,15 @@ +package net.sourceforge.jnlp.browsertesting.browsers; + +import net.sourceforge.jnlp.browsertesting.Browsers; + +public class Chrome extends MozillaFamilyLinuxBrowser { + + public Chrome(String bin) { + super(bin); + } + + @Override + public Browsers getID() { + return Browsers.googleChrome; + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Chromium.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Chromium.java new file mode 100644 index 0000000..616d38a --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Chromium.java @@ -0,0 +1,15 @@ +package net.sourceforge.jnlp.browsertesting.browsers; + +import net.sourceforge.jnlp.browsertesting.Browsers; + +public class Chromium extends MozillaFamilyLinuxBrowser { + + public Chromium(String bin) { + super(bin); + } + + @Override + public Browsers getID() { + return Browsers.chromiumBrowser; + } +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Epiphany.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Epiphany.java new file mode 100644 index 0000000..3adc3d8 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Epiphany.java @@ -0,0 +1,18 @@ +package net.sourceforge.jnlp.browsertesting.browsers; + +import net.sourceforge.jnlp.browsertesting.Browsers; + +public class Epiphany extends MozillaFamilyLinuxBrowser { + + public Epiphany(String bin) { + super(bin); + } + + @Override + public Browsers getID() { + return Browsers.epiphany; + } + + + +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Firefox.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Firefox.java new file mode 100644 index 0000000..8458bce --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Firefox.java @@ -0,0 +1,29 @@ +package net.sourceforge.jnlp.browsertesting.browsers; + +import java.util.Arrays; +import java.util.List; +import net.sourceforge.jnlp.browsertesting.Browsers; + +public class Firefox extends MozillaFamilyLinuxBrowser { + + public Firefox(String bin) { + super(bin); + } + + String[] cs={"-no-remote", "-new-tab"}; + + @Override + public Browsers getID() { + return Browsers.firefox; + } + + @Override + public List<String> getComaptibilitySwitches() { + return Arrays.asList(cs); + } + + + + + +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/LinuxBrowser.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/LinuxBrowser.java new file mode 100644 index 0000000..edc95e0 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/LinuxBrowser.java @@ -0,0 +1,60 @@ +package net.sourceforge.jnlp.browsertesting.browsers; + +import net.sourceforge.jnlp.browsertesting.Browser; + + +public abstract class LinuxBrowser implements Browser{ + public static final String DEFAULT_PLUGIN_NAME="libjavaplugin.so"; + public static final String DEFAULT_BIN_PATH="/usr/bin/"; + + protected final String bin; + protected String fsdir="unknown"; + + public LinuxBrowser(String bin) { + this.bin = bin; + } + + + + @Override + public String getBin() { + return bin; + } + +// @Override +// public void setBin(String bin) { +// this.bin=bin; +// } + + @Override + public String getDefaultBin() { + return DEFAULT_BIN_PATH+getID().toExec(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Browser)) return false; + Browser b=(Browser) obj; + return b.getBin().equals(getBin()); + } + + @Override + public int hashCode() { + int hash = 5; + hash = 59 * hash + (this.bin != null ? this.bin.hashCode() : 0); + return hash; + } + + @Override + public String getDefaultPluginExpectedLocation() { + if (System.getProperty("os.arch").contains("64")) { + return "/usr/lib64/"+fsdir+"/plugins"; + } else { + return "/usr/lib/"+fsdir+"/plugins"; + + } + } + + + +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Midory.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Midory.java new file mode 100644 index 0000000..fc563fb --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Midory.java @@ -0,0 +1,18 @@ +package net.sourceforge.jnlp.browsertesting.browsers; + +import net.sourceforge.jnlp.browsertesting.Browsers; + +public class Midory extends MozillaFamilyLinuxBrowser { + + public Midory(String bin) { + super(bin); + } + + @Override + public Browsers getID() { + return Browsers.midori; + } + + + +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/MozillaFamilyLinuxBrowser.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/MozillaFamilyLinuxBrowser.java new file mode 100644 index 0000000..c8d1e85 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/MozillaFamilyLinuxBrowser.java @@ -0,0 +1,29 @@ +package net.sourceforge.jnlp.browsertesting.browsers; + +import java.util.List; + +public abstract class MozillaFamilyLinuxBrowser extends LinuxBrowser{ + + public MozillaFamilyLinuxBrowser(String bin) { + super(bin); + fsdir="mozilla"; + } + + + @Override + public List<String> getComaptibilitySwitches() { + return null; + } + + @Override + public List<String> getDefaultSwitches() { + return null; + } + + @Override + public String getUserDefaultPluginExpectedLocation() { + return System.getProperty("user.home")+"/.mozilla/plugins"; + } + + +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Opera.java b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Opera.java new file mode 100644 index 0000000..edbf57f --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Opera.java @@ -0,0 +1,37 @@ +package net.sourceforge.jnlp.browsertesting.browsers; + +import java.util.Arrays; +import java.util.List; +import net.sourceforge.jnlp.browsertesting.Browsers; + +public class Opera extends LinuxBrowser { + + public Opera(String bin) { + super(bin); + fsdir="opera"; + } + + @Override + public Browsers getID() { + return Browsers.opera; + } + + @Override + public String getUserDefaultPluginExpectedLocation() { + return null; + } + + + String[] cs={"-nosession", "-nomail", "-nolirc", "-newtab"}; + + @Override + public List<String> getComaptibilitySwitches() { + return Arrays.asList(cs); + } + + @Override + public List<String> getDefaultSwitches() { + return null; + } + +}
\ No newline at end of file |