From: <cr...@us...> - 2009-01-24 04:02:54
|
Revision: 4905 http://jnode.svn.sourceforge.net/jnode/?rev=4905&view=rev Author: crawley Date: 2009-01-24 04:02:50 +0000 (Sat, 24 Jan 2009) Log Message: ----------- More work on the command test harness, etc Modified Paths: -------------- trunk/shell/src/emu/org/jnode/emu/DeviceManager.java trunk/shell/src/emu/org/jnode/emu/Emu.java trunk/shell/src/emu/org/jnode/emu/EmuException.java trunk/shell/src/shell/org/jnode/shell/CommandShell.java trunk/shell/src/test/org/jnode/test/shell/command/posix/posix-command-tests.xml trunk/shell/src/test/org/jnode/test/shell/harness/CommandTestRunner.java trunk/shell/src/test/org/jnode/test/shell/harness/TestHarness.java trunk/shell/src/test/org/jnode/test/shell/harness/TestRunnable.java trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecification.java trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecificationParser.java Added Paths: ----------- trunk/shell/src/test/org/jnode/test/shell/bjorne/BjornePseudoPlugin.java trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml trunk/shell/src/test/org/jnode/test/shell/harness/JNodeTestRunnerBase.java trunk/shell/src/test/org/jnode/test/shell/harness/PseudoPlugin.java trunk/shell/src/test/org/jnode/test/shell/harness/ScriptTestRunner.java trunk/shell/src/test/org/jnode/test/shell/harness/TestCommandShell.java trunk/shell/src/test/org/jnode/test/shell/harness/TestEmu.java Modified: trunk/shell/src/emu/org/jnode/emu/DeviceManager.java =================================================================== --- trunk/shell/src/emu/org/jnode/emu/DeviceManager.java 2009-01-24 02:16:41 UTC (rev 4904) +++ trunk/shell/src/emu/org/jnode/emu/DeviceManager.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; + import org.apache.log4j.Logger; import org.jnode.driver.AbstractDeviceManager; import org.jnode.driver.Device; Modified: trunk/shell/src/emu/org/jnode/emu/Emu.java =================================================================== --- trunk/shell/src/emu/org/jnode/emu/Emu.java 2009-01-24 02:16:41 UTC (rev 4904) +++ trunk/shell/src/emu/org/jnode/emu/Emu.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -51,9 +51,9 @@ * An Emu is also a large flightless bird ... which seems kind of appropriate. * * @author Levente S\u00e1ntha - * @author Stephen Crawley + * @author cr...@jn... */ -public abstract class Emu { +public class Emu { private static final String[] ALL_PROJECTS = new String[]{ "core", "distr", "fs", "gui", "net", "shell", "sound", "textui" }; Modified: trunk/shell/src/emu/org/jnode/emu/EmuException.java =================================================================== --- trunk/shell/src/emu/org/jnode/emu/EmuException.java 2009-01-24 02:16:41 UTC (rev 4904) +++ trunk/shell/src/emu/org/jnode/emu/EmuException.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -2,6 +2,8 @@ public class EmuException extends Exception { + private static final long serialVersionUID = 1L; + public EmuException(String message) { super(message); } Modified: trunk/shell/src/shell/org/jnode/shell/CommandShell.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/CommandShell.java 2009-01-24 02:16:41 UTC (rev 4904) +++ trunk/shell/src/shell/org/jnode/shell/CommandShell.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -921,7 +921,7 @@ * @param stream A real stream or a stream marker * @return the real stream that the first argument maps to. */ - CommandIO resolveStream(CommandIO stream) { + protected CommandIO resolveStream(CommandIO stream) { if (stream == CommandLine.DEFAULT_STDIN) { return getInputStream(); } else if (stream == CommandLine.DEFAULT_STDOUT) { Added: trunk/shell/src/test/org/jnode/test/shell/bjorne/BjornePseudoPlugin.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/bjorne/BjornePseudoPlugin.java (rev 0) +++ trunk/shell/src/test/org/jnode/test/shell/bjorne/BjornePseudoPlugin.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -0,0 +1,31 @@ +package org.jnode.test.shell.bjorne; + +import javax.naming.NamingException; + +import org.jnode.naming.InitialNaming; +import org.jnode.shell.CommandInterpreter; +import org.jnode.shell.ShellManager; +import org.jnode.shell.bjorne.BjorneInterpreter; + +public class BjornePseudoPlugin { + private static final CommandInterpreter.Factory FACTORY = new CommandInterpreter.Factory() { + public CommandInterpreter create() { + return new BjorneInterpreter(); + } + + public String getName() { + return "bjorne"; + } + }; + + /** + * Initialize a new instance + * + * @param descriptor + */ + public BjornePseudoPlugin() throws NamingException { + ShellManager mgr = InitialNaming.lookup(ShellManager.NAME); + mgr.registerInterpreterFactory(FACTORY); + } + +} Added: trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml (rev 0) +++ trunk/shell/src/test/org/jnode/test/shell/bjorne/bjorne-shell-tests.xml 2009-01-24 04:02:50 UTC (rev 4905) @@ -0,0 +1,30 @@ +<testSpecs> +<testSpec> +<title>simple</title> +<command>test</command> +<runMode>AS_SCRIPT</runMode> +<plugins> +<plugin> +<id>org.jnode.shell.bjorne</id> +<class>org.jnode.test.shell.bjorne.BjornePseudoPlugin</class> +</plugin> +</plugins> +<script>#!bjorne +echo HI +</script> +<output>HI +</output> +<rc>0</rc> +</testSpec> +<testSpec> +<title>#if ... then ... fi</title> +<command>test</command> +<runMode>AS_SCRIPT</runMode> +<script>#!bjorne +if true ; then echo HI ; fi +</script> +<output>HI +</output> +<rc>0</rc> +</testSpec> +</testSpecs> \ No newline at end of file Modified: trunk/shell/src/test/org/jnode/test/shell/command/posix/posix-command-tests.xml =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/command/posix/posix-command-tests.xml 2009-01-24 02:16:41 UTC (rev 4904) +++ trunk/shell/src/test/org/jnode/test/shell/command/posix/posix-command-tests.xml 2009-01-24 04:02:50 UTC (rev 4905) @@ -1,12 +1,12 @@ <testSpecs> <testSpec> -<title>Test 'true'</title> +<title>true command</title> <command>org.jnode.shell.command.posix.TrueCommand</command> <runMode>AS_ALIAS</runMode> <rc>0</rc> </testSpec> <testSpec> -<title>Test 'false'</title> +<title>false command</title> <command>org.jnode.shell.command.posix.FalseCommand</command> <runMode>AS_ALIAS</runMode> <rc>1</rc> Modified: trunk/shell/src/test/org/jnode/test/shell/harness/CommandTestRunner.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/harness/CommandTestRunner.java 2009-01-24 02:16:41 UTC (rev 4904) +++ trunk/shell/src/test/org/jnode/test/shell/harness/CommandTestRunner.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -5,9 +5,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.PrintStream; -import java.lang.reflect.Method; import org.jnode.shell.CommandInfo; import org.jnode.shell.CommandInvoker; @@ -20,7 +18,7 @@ /** - * This TestRunner runs a a class by calling its 'static void main(Sting[])' entry + * This TestRunner runs a class by calling its 'static void main(String[])' entry * point. Note that classes that call System.exit(status) are problematic. * * @author cr...@jn... @@ -32,56 +30,22 @@ private final TestSpecification spec; private final TestHarness harness; + private final CommandShell shell; @SuppressWarnings("unused") private final boolean usingEmu; - - private static boolean emuInitialized; - private static boolean emuAvailable; - private static CommandShell shell; public CommandTestRunner(TestSpecification spec, TestHarness harness) { this.spec = spec; this.harness = harness; - this.usingEmu = initEmu(harness.getRoot()); + this.usingEmu = TestEmu.initEmu(harness.getRoot()); + this.shell = TestEmu.getShell(); } - private static synchronized boolean initEmu(File root) { - if (!emuInitialized) { - // This is a bit of a hack. We don't want class loader dependencies - // on the Emu code because that won't work when we run on JNode. But - // we need to use Emu if we are running tests on the dev't platform. - // The following infers that we are running on the dev't platform if - // the 'Emu' class is not loadable. - try { - Class<?> cls = Class.forName("org.jnode.emu.Emu"); - Method initMethod = cls.getMethod("initEnv", File.class); - initMethod.invoke(null, root); - emuAvailable = true; - } catch (Throwable ex) { - // debug ... - ex.printStackTrace(System.err); - emuAvailable = false; - } - try { - if (emuAvailable) { - shell = new CommandShell(); - } else { - shell = (CommandShell) ShellUtils.getCurrentShell(); - } - } catch (Exception ex) { - // debug ... - ex.printStackTrace(System.err); - throw new RuntimeException(ex); - } - emuInitialized = true; - } - return emuAvailable; - } - @Override public int run() throws Exception { String[] args = spec.getArgs().toArray(new String[0]); + // FIXME change this to a shell provided by getShell??? AliasManager aliasMgr = ShellUtils.getAliasManager(); CommandInvoker invoker = new ThreadCommandInvoker(shell); CommandLine cmdLine = new CommandLine(spec.getCommand(), args); @@ -94,13 +58,13 @@ Thread.currentThread().getContextClassLoader(); cmdInfo = new CommandInfo(cl.loadClass(spec.getCommand()), false); } - invoker.invoke(cmdLine, cmdInfo); - return check() ? 0 : 1; + int rc = invoker.invoke(cmdLine, cmdInfo); + return check(rc) ? 0 : 1; } - private boolean check() { - // When a class is run this way we cannot capture the RC. + private boolean check(int rc) { return + harness.expect(rc, spec.getRc(), "return code") && harness.expect(outBucket.toString(), spec.getOutputContent(), "output content") && harness.expect(errBucket.toString(), spec.getErrorContent(), "err content"); } Added: trunk/shell/src/test/org/jnode/test/shell/harness/JNodeTestRunnerBase.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/harness/JNodeTestRunnerBase.java (rev 0) +++ trunk/shell/src/test/org/jnode/test/shell/harness/JNodeTestRunnerBase.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -0,0 +1,68 @@ +package org.jnode.test.shell.harness; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.jnode.naming.InitialNaming; +import org.jnode.plugin.PluginManager; +import org.jnode.shell.CommandShell; +import org.jnode.shell.ShellException; +import org.jnode.test.shell.harness.TestSpecification.PluginSpec; + +public abstract class JNodeTestRunnerBase implements TestRunnable { + protected ByteArrayOutputStream outBucket; + protected ByteArrayOutputStream errBucket; + + protected final TestSpecification spec; + protected final TestHarness harness; + + protected final boolean usingEmu; + + public JNodeTestRunnerBase(TestSpecification spec, TestHarness harness) { + super(); + this.spec = spec; + this.harness = harness; + this.usingEmu = TestEmu.initEmu(harness.getRoot()); + } + + public CommandShell getShell() throws ShellException { + CommandShell shell = TestEmu.getShell(); + if (shell == null) { + shell = new TestCommandShell(System.in, System.out, System.err); + shell.configureShell(); + } + return shell; + } + + @Override + public void cleanup() { + } + + @Override + public void setup() { + for (PluginSpec plugin : spec.getRequiredPlugins()) { + ensurePluginLoaded(plugin); + } + System.setIn(new ByteArrayInputStream(spec.getInputContent().getBytes())); + outBucket = new ByteArrayOutputStream(); + errBucket = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outBucket)); + System.setErr(new PrintStream(errBucket)); + } + + protected void ensurePluginLoaded(PluginSpec pluginSpec) { + if (usingEmu) { + TestEmu.loadPseudoPlugin(pluginSpec.pseudoPluginClassName); + } else { + String ver = (pluginSpec.pluginVersion.length() == 0) ? + System.getProperty("os.version") : pluginSpec.pluginVersion; + try { + PluginManager mgr = InitialNaming.lookup(PluginManager.NAME); + mgr.getRegistry().loadPlugin(mgr.getLoaderManager(), pluginSpec.pluginId, ver); + } catch (Exception ex) { + throw new RuntimeException("Cannot load plugin '" + pluginSpec.pluginId + "/" + ver + "'"); + } + } + } +} Added: trunk/shell/src/test/org/jnode/test/shell/harness/PseudoPlugin.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/harness/PseudoPlugin.java (rev 0) +++ trunk/shell/src/test/org/jnode/test/shell/harness/PseudoPlugin.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -0,0 +1,5 @@ +package org.jnode.test.shell.harness; + +public interface PseudoPlugin { + +} Added: trunk/shell/src/test/org/jnode/test/shell/harness/ScriptTestRunner.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/harness/ScriptTestRunner.java (rev 0) +++ trunk/shell/src/test/org/jnode/test/shell/harness/ScriptTestRunner.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -0,0 +1,58 @@ +/** + * + */ +package org.jnode.test.shell.harness; + +import java.io.File; +import java.io.FileWriter; +import java.io.Writer; + + +/** + * This TestRunner runs a script + * + * @author cr...@jn... + */ +class ScriptTestRunner extends JNodeTestRunnerBase implements TestRunnable { + + + + private File tempScriptFile; + + public ScriptTestRunner(TestSpecification spec, TestHarness harness) { + super(spec, harness); + } + + @Override + public int run() throws Exception { +// String[] args = spec.getArgs().toArray(new String[0]); +// CommandLine cmdLine = new CommandLine(spec.getCommand(), args); + tempScriptFile = new File(System.getProperty("java.io.tmpdir"), spec.getCommand()); + Writer w = null; + try { + w = new FileWriter(tempScriptFile); + w.write(spec.getScriptContent()); + w.write('\n'); + } finally { + w.close(); + } + int rc = getShell().runCommandFile(tempScriptFile); + return check(rc) ? 0 : 1; + } + + private boolean check(int rc) { + return + // harness.expect(rc, spec.getRc(), "return code") && + harness.expect(outBucket.toString(), spec.getOutputContent(), "output content") && + harness.expect(errBucket.toString(), spec.getErrorContent(), "err content"); + } + + @Override + public void cleanup() { + if (tempScriptFile != null) { + tempScriptFile.delete(); + } + super.cleanup(); + } + +} \ No newline at end of file Added: trunk/shell/src/test/org/jnode/test/shell/harness/TestCommandShell.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/harness/TestCommandShell.java (rev 0) +++ trunk/shell/src/test/org/jnode/test/shell/harness/TestCommandShell.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -0,0 +1,75 @@ +package org.jnode.test.shell.harness; + +import java.io.File; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.Writer; + +import org.jnode.driver.console.CompletionInfo; +import org.jnode.driver.console.ConsoleEvent; +import org.jnode.driver.console.InputHistory; +import org.jnode.driver.console.TextConsole; +import org.jnode.shell.CommandInfo; +import org.jnode.shell.CommandInterpreter; +import org.jnode.shell.CommandInvoker; +import org.jnode.shell.CommandLine; +import org.jnode.shell.CommandShell; +import org.jnode.shell.CommandThread; +import org.jnode.shell.ShellException; +import org.jnode.shell.alias.AliasManager; +import org.jnode.shell.io.CommandIO; +import org.jnode.shell.io.CommandInput; +import org.jnode.shell.io.CommandInputOutput; +import org.jnode.shell.io.CommandOutput; +import org.jnode.shell.io.NullInputStream; +import org.jnode.shell.io.NullOutputStream; +import org.jnode.shell.syntax.ArgumentBundle; +import org.jnode.shell.syntax.SyntaxManager; + +/** + * This class modify the shell's stream resolution mechanism so that + * in/out/err resolve to the streams supplied in the constructor. + * + * @author cr...@jn... + */ +public class TestCommandShell extends CommandShell { + + private final CommandInput cin; + private final CommandOutput cout; + private final CommandOutput cerr; + + public TestCommandShell(InputStream in, PrintStream out, PrintStream err) + throws ShellException { + super(); + this.cin = new CommandInput(in); + this.cout = new CommandOutput(out); + this.cerr = new CommandOutput(err); + } + + @Override + public PrintWriter getErr() { + return cerr.getPrintWriter(true); + } + + @Override + public PrintWriter getOut() { + return cout.getPrintWriter(false); + } + + @Override + protected CommandIO resolveStream(CommandIO stream) { + if (stream == CommandLine.DEFAULT_STDIN) { + return cin; + } else if (stream == CommandLine.DEFAULT_STDOUT) { + return cout; + } else if (stream == CommandLine.DEFAULT_STDERR) { + return cerr; + } else if (stream == CommandLine.DEVNULL || stream == null) { + return new CommandInputOutput(new NullInputStream(), new NullOutputStream()); + } else { + return stream; + } + } +} Added: trunk/shell/src/test/org/jnode/test/shell/harness/TestEmu.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/harness/TestEmu.java (rev 0) +++ trunk/shell/src/test/org/jnode/test/shell/harness/TestEmu.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -0,0 +1,83 @@ +package org.jnode.test.shell.harness; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.util.HashSet; +import java.util.Set; + +import org.jnode.shell.CommandShell; +import org.jnode.shell.ShellUtils; + +/** + * This class performs Emu and CommandShell initialization without exposing + * the Emu APIs at the class loader level. + * + * @author cr...@jn... + */ +public class TestEmu { + + private static boolean emuInitialized; + private static boolean emuAvailable; + private static CommandShell shell; + + @SuppressWarnings("unused") + private static Object emuObject; + + private static Set<String> loadedPseudoPlugins = new HashSet<String>(); + + public static synchronized boolean initEmu(File root) { + if (!emuInitialized) { + // This is a bit of a hack. We don't want class loader dependencies + // on the Emu code because that won't work when we run on JNode. But + // we need to use Emu if we are running tests on the dev't platform. + // The following infers that we are running on the dev't platform if + // the 'Emu' class is not loadable. + try { + Class<?> cls = Class.forName("org.jnode.emu.Emu"); + Constructor<?> constructor = cls.getConstructor(File.class); + emuObject = constructor.newInstance(root); + emuAvailable = true; + } catch (Throwable ex) { + // debug ... + ex.printStackTrace(System.err); + emuAvailable = false; + } + try { + if (emuAvailable) { + shell = null; + } else { + shell = (CommandShell) ShellUtils.getCurrentShell(); + } + } catch (Exception ex) { + // debug ... + ex.printStackTrace(System.err); + throw new RuntimeException(ex); + } + emuInitialized = true; + } + return emuAvailable; + } + + public static synchronized CommandShell getShell() { + if (!emuInitialized) { + throw new IllegalStateException("Emu not initialized"); + } + return shell; + } + + public static synchronized void loadPseudoPlugin(String pseudoPluginClassName) { + if (!emuInitialized) { + throw new IllegalStateException("Emu not initialized"); + } + if (!loadedPseudoPlugins.contains(pseudoPluginClassName)) { + try { + Class<?> clazz = Class.forName(pseudoPluginClassName); + clazz.newInstance(); + } catch (Exception ex) { + throw new RuntimeException("Cannot load '" + pseudoPluginClassName + "'", ex); + } + loadedPseudoPlugins.add(pseudoPluginClassName); + } + } + +} Modified: trunk/shell/src/test/org/jnode/test/shell/harness/TestHarness.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/harness/TestHarness.java 2009-01-24 02:16:41 UTC (rev 4904) +++ trunk/shell/src/test/org/jnode/test/shell/harness/TestHarness.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -24,8 +24,8 @@ private PrintWriter reportWriter; private int testCount; - private int errorCount; private int failureCount; + private int exceptionCount; private TestSpecification spec = null; private InputStream savedIn; private PrintStream savedOut; @@ -95,8 +95,8 @@ } } } - report("Ran " + testCount + " tests with " + errorCount + - " errors and " + failureCount + " failures"); + report("Ran " + testCount + " tests with " + failureCount + + " test failures and " + exceptionCount + " errors (exceptions)"); } private void usage() { @@ -112,6 +112,7 @@ } private void execute(TestSpecification spec) { + this.spec = spec; reportVerbose("Running test '" + spec.getTitle() + "'"); testCount++; try { @@ -123,6 +124,9 @@ case AS_ALIAS: runner = new CommandTestRunner(spec, this); break; + case AS_SCRIPT: + runner = new ScriptTestRunner(spec, this); + break; default: reportVerbose("Run mode '" + spec.getRunMode() + "' not implemented"); return; @@ -130,14 +134,15 @@ try { setup(); runner.setup(); - errorCount += runner.run(); + failureCount += runner.run(); } finally { runner.cleanup(); cleanup(); } } catch (Throwable ex) { + report("Uncaught exception in test '" + spec.getTitle() + "': stacktrace follows."); ex.printStackTrace(reportWriter); - failureCount++; + exceptionCount++; } reportVerbose("Completed test '" + spec.getTitle() + "'"); } @@ -187,14 +192,18 @@ } } - public boolean expect(Object expected, Object actual, String desc) { + public boolean expect(Object actual, Object expected, String desc) { if (expected.equals(actual)) { return true; } - report("Incorrect test result for '" + desc + "' in test '" + spec.getTitle() + "'"); - report(" expected '" + expected + "': got '" + actual + "'"); + report("Incorrect test result for " + asString(desc) + " in test " + asString(spec.getTitle())); + report(" expected " + asString(expected) + ": got " + asString(actual) + "."); return false; } + + private String asString(Object obj) { + return (obj == null) ? "null" : ("'" + obj + "'"); + } public File getRoot() { // FIXME ... this should be the workspace root. Modified: trunk/shell/src/test/org/jnode/test/shell/harness/TestRunnable.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/harness/TestRunnable.java 2009-01-24 02:16:41 UTC (rev 4904) +++ trunk/shell/src/test/org/jnode/test/shell/harness/TestRunnable.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -5,7 +5,7 @@ * use / extend Runnable because we need to propagate any exceptions * in the {@link TestRunnable.run()} method. * - * @author stephen + * @author cr...@jn... */ public interface TestRunnable { Modified: trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecification.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecification.java 2009-01-24 02:16:41 UTC (rev 4904) +++ trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecification.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -11,6 +11,20 @@ */ public class TestSpecification { + public static class PluginSpec { + public final String pluginId; + public final String pluginVersion; + public final String pseudoPluginClassName; + + public PluginSpec(String pluginId, String pluginVersion, + String pseudoPluginClassName) { + super(); + this.pluginId = pluginId; + this.pluginVersion = pluginVersion; + this.pseudoPluginClassName = pseudoPluginClassName; + } + } + public static enum RunMode { AS_SCRIPT, AS_CLASS, @@ -20,19 +34,23 @@ private final RunMode runMode; private final String command; private final List<String> args; + private final String scriptContent; private final String inputContent; private final String outputContent; private final String errorContent; private final String title; + private final List<PluginSpec> requiredPlugins; private final int rc; private final Map<File, String> fileMap; - public TestSpecification(RunMode runMode, String command, + public TestSpecification(RunMode runMode, String command, String scriptContent, String inputContent, String outputContent, String errorContent, - String title, int rc, List<String> args, Map<File, String> fileMap) { + String title, int rc, List<String> args, Map<File, String> fileMap, + List<PluginSpec> requiredPlugins) { super(); this.runMode = runMode; this.command = command; + this.scriptContent = scriptContent; this.inputContent = inputContent; this.outputContent = outputContent; this.errorContent = errorContent; @@ -40,6 +58,7 @@ this.rc = rc; this.args = args; this.fileMap = fileMap; + this.requiredPlugins = requiredPlugins; } public String getOutputContent() { @@ -73,6 +92,10 @@ public List<String> getArgs() { return args; } + + public String getScriptContent() { + return scriptContent; + } public String getInputContent() { return inputContent; @@ -81,4 +104,8 @@ public String getTitle() { return title; } + + public List<PluginSpec> getRequiredPlugins() { + return requiredPlugins; + } } Modified: trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecificationParser.java =================================================================== --- trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecificationParser.java 2009-01-24 02:16:41 UTC (rev 4904) +++ trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecificationParser.java 2009-01-24 04:02:50 UTC (rev 4905) @@ -12,6 +12,7 @@ import net.n3.nanoxml.StdXMLReader; import net.n3.nanoxml.XMLParserFactory; +import org.jnode.test.shell.harness.TestSpecification.PluginSpec; import org.jnode.test.shell.harness.TestSpecification.RunMode; public class TestSpecificationParser { @@ -48,33 +49,48 @@ RunMode runMode = RunMode.valueOf(extractElementValue(elem, "runMode", "AS_CLASS")); String title = extractElementValue(elem, "title"); String command = extractElementValue(elem, "command"); + String scriptContent = extractElementValue(elem, "script", ""); String inputContent = extractElementValue(elem, "input", ""); String outputContent = extractElementValue(elem, "output", ""); String errorContent = extractElementValue(elem, "error", ""); int rc; try { - rc = Integer.parseInt(extractElementValue(elem, "error", "0").trim()); + rc = Integer.parseInt(extractElementValue(elem, "rc", "0").trim()); } catch (NumberFormatException ex) { throw new TestSpecificationException("'rc' is not an integer"); } - IXMLElement child = elem.getFirstChildNamed("args"); - List<String> args = new ArrayList<String>(); - if (child != null) { - for (Object obj : child.getChildren()) { + List<String> args = parseArgs(elem.getFirstChildNamed("args")); + Map<File, String> fileMap = parseFiles(elem.getFirstChildNamed("files")); + List<PluginSpec> plugins = parsePlugins(elem.getFirstChildNamed("plugins")); + return new TestSpecification( + runMode, command, scriptContent, inputContent, outputContent, errorContent, + title, rc, args, fileMap, plugins); + } + + private List<PluginSpec> parsePlugins(IXMLElement pluginsElem) throws TestSpecificationException { + List<PluginSpec> plugins = new ArrayList<PluginSpec>(); + if (pluginsElem != null) { + for (Object obj : pluginsElem.getChildren()) { if (obj instanceof IXMLElement) { - IXMLElement argChild = (IXMLElement) obj; - if (!argChild.getName().equals("arg")) { + IXMLElement child = (IXMLElement) obj; + if (!child.getName().equals("plugin")) { throw new TestSpecificationException( - "Child elements of 'args' should be 'arg' not '" + argChild.getName() + "'"); + "Child elements of 'plugins' should be 'plugin' not '" + child.getName() + "'"); } - args.add(argChild.getContent()); + String pluginId = extractElementValue(child, "id"); + String pluginVersion = extractElementValue(child, "version", ""); + String pseudoPluginClassName = extractElementValue(child, "class"); + plugins.add(new PluginSpec(pluginId, pluginVersion, pseudoPluginClassName)); } } } - child = elem.getFirstChildNamed("files"); + return plugins; + } + + private Map<File, String> parseFiles(IXMLElement filesElem) throws TestSpecificationException { Map<File, String> fileMap = new HashMap<File, String>(); - if (child != null) { - for (Object obj : child.getChildren()) { + if (filesElem != null) { + for (Object obj : filesElem.getChildren()) { if (obj instanceof IXMLElement) { IXMLElement fileChild = (IXMLElement) obj; if (!fileChild.getName().equals("file")) { @@ -87,18 +103,34 @@ } } } - return new TestSpecification( - runMode, command, inputContent, outputContent, errorContent, - title, rc, args, fileMap); + return fileMap; } + private List<String> parseArgs(IXMLElement argsElem) throws TestSpecificationException { + List<String> args = new ArrayList<String>(); + if (argsElem != null) { + for (Object obj : argsElem.getChildren()) { + if (obj instanceof IXMLElement) { + IXMLElement argChild = (IXMLElement) obj; + if (!argChild.getName().equals("arg")) { + throw new TestSpecificationException( + "Child elements of 'args' should be 'arg' not '" + argChild.getName() + "'"); + } + args.add(argChild.getContent()); + } + } + } + return args; + } + private String extractElementValue(IXMLElement parent, String name) throws TestSpecificationException { IXMLElement elem = parent.getFirstChildNamed(name); if (elem == null) { throw new TestSpecificationException( "Element '" + name + "' not found in '" + parent.getName() + "'"); } else { - return elem.getContent(); + String res = elem.getContent(); + return (res == null) ? "" : res; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |