|
From: <cr...@us...> - 2009-01-18 13:23:25
|
Revision: 4887
http://jnode.svn.sourceforge.net/jnode/?rev=4887&view=rev
Author: crawley
Date: 2009-01-18 13:23:15 +0000 (Sun, 18 Jan 2009)
Log Message:
-----------
First checkin of a test harness for testing JNode commands and scripts.
(This entails moving most of Emu into the 'shell' project.)
Modified Paths:
--------------
trunk/shell/.classpath
trunk/shell/build.xml
trunk/shell/descriptors/org.jnode.test.shell.xml
trunk/shell/src/test/org/jnode/test/shell/Cassowary.java
Added Paths:
-----------
trunk/shell/src/emu/
trunk/shell/src/emu/org/
trunk/shell/src/emu/org/jnode/
trunk/shell/src/emu/org/jnode/emu/
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/test/org/jnode/test/shell/command/
trunk/shell/src/test/org/jnode/test/shell/command/posix/
trunk/shell/src/test/org/jnode/test/shell/command/posix/TrueTest.xml
trunk/shell/src/test/org/jnode/test/shell/harness/
trunk/shell/src/test/org/jnode/test/shell/harness/ClassTestRunner.java
trunk/shell/src/test/org/jnode/test/shell/harness/CommandTestRunner.java
trunk/shell/src/test/org/jnode/test/shell/harness/Test.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/TestSpecificationException.java
Removed Paths:
-------------
trunk/distr/src/emu/org/jnode/emu/DeviceManager.java
trunk/distr/src/emu/org/jnode/emu/Emu.java
trunk/distr/src/emu/org/jnode/emu/EmuException.java
Deleted: trunk/distr/src/emu/org/jnode/emu/DeviceManager.java
===================================================================
--- trunk/distr/src/emu/org/jnode/emu/DeviceManager.java 2009-01-18 11:04:39 UTC (rev 4886)
+++ trunk/distr/src/emu/org/jnode/emu/DeviceManager.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -1,105 +0,0 @@
-/*
- * $Id$
- */
-package org.jnode.emu;
-
-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;
-import org.jnode.driver.DeviceFinder;
-import org.jnode.driver.DeviceToDriverMapper;
-import org.jnode.driver.DriverException;
-
-/**
- * @author Levente S\u00e1ntha
- */
-public class DeviceManager extends AbstractDeviceManager {
- public static final Logger log = Logger.getLogger(DeviceManager.class);
-
- public static final DeviceManager INSTANCE = new DeviceManager();
-
- private List<DeviceFinder> finders = new ArrayList<DeviceFinder>();
-
- private List<DeviceToDriverMapper> mappers = new ArrayList<DeviceToDriverMapper>();
-
- private DeviceManager() {
- }
-
- public void removeAll() {
- finders.clear();
- mappers.clear();
-
- for (Device device : getDevices()) {
- try {
- unregister(device);
- } catch (DriverException e) {
- log.error("can't unregister " + device);
- }
- }
- }
-
- public void add(DeviceFinder finder, DeviceToDriverMapper mapper) {
- boolean doStart = false;
-
- if (!finders.contains(finder)) {
- finders.add(finder);
- doStart = true;
- }
-
- if (!mappers.contains(mapper)) {
- mappers.add(mapper);
- doStart = true;
- }
-
- if (doStart) {
- start();
- }
- }
-
- /**
- * Start this manager
- */
- public final void start() {
- // Thread thread = new Thread()
- // {
- // public void run()
- // {
- log.debug("Loading extensions ...");
- loadExtensions();
- log.debug("Extensions loaded !");
- // }
- // };
- // thread.start();
-
- try {
- // must be called before findDeviceDrivers
- log.debug("findDevices ...");
- findDevices();
-
- log.debug("findDeviceDrivers ...");
- findDeviceDrivers();
-
- log.debug("StubDeviceManager initialized !");
- } catch (InterruptedException e) {
- log.fatal("can't find devices", e);
- }
- }
-
- protected final void refreshFinders(List<DeviceFinder> finders) {
- log.info("refreshFinders");
- finders.clear();
- finders.addAll(this.finders);
- }
-
- protected final void refreshMappers(List<DeviceToDriverMapper> mappers) {
- log.info("refreshMappers");
- mappers.clear();
- mappers.addAll(this.mappers);
-
- // Now sort them
- Collections.sort(mappers, MapperComparator.INSTANCE);
- }
-}
Deleted: trunk/distr/src/emu/org/jnode/emu/Emu.java
===================================================================
--- trunk/distr/src/emu/org/jnode/emu/Emu.java 2009-01-18 11:04:39 UTC (rev 4886)
+++ trunk/distr/src/emu/org/jnode/emu/Emu.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -1,228 +0,0 @@
-/*
- * $Id: NameSpace.java 4564 2008-09-18 22:01:10Z fduminy $
- *
- * JNode.org
- * Copyright (C) 2003-2006 JNode.org
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-package org.jnode.emu;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-
-import javax.naming.NamingException;
-
-import org.jnode.emu.naming.BasicNameSpace;
-import org.jnode.emu.plugin.model.DummyExtensionPoint;
-import org.jnode.naming.InitialNaming;
-import org.jnode.nanoxml.XMLElement;
-import org.jnode.shell.ShellManager;
-import org.jnode.shell.alias.AliasManager;
-import org.jnode.shell.alias.def.DefaultAliasManager;
-import org.jnode.shell.def.DefaultShellManager;
-import org.jnode.shell.help.HelpFactory;
-import org.jnode.shell.help.def.DefaultHelpFactory;
-import org.jnode.shell.syntax.DefaultSyntaxManager;
-import org.jnode.shell.syntax.SyntaxBundle;
-import org.jnode.shell.syntax.SyntaxManager;
-import org.jnode.shell.syntax.SyntaxSpecAdapter;
-import org.jnode.shell.syntax.SyntaxSpecLoader;
-import org.jnode.shell.syntax.XMLSyntaxSpecAdapter;
-
-/**
- * This class is the core of a light-weight JNode emulator that allows (some) JNode
- * applications to be run using a classic JVM in the context of a JNode development sandbox.
- *
- * @author Levente S\u00e1ntha
- * @author Stephen Crawley
- */
-public abstract class Emu {
- private static final String[] ALL_PROJECTS = new String[]{
- "core", "distr", "fs", "gui", "net", "shell", "sound", "textui"
- };
-
- private static final String[] PLUGIN_NAMES = new String[]{
- "org.jnode.shell.command",
- "org.jnode.shell.command.driver.console",
- "org.jnode.apps.editor",
- "org.jnode.apps.edit",
- "org.jnode.apps.console",
- };
-
- /**
- * Initialize a minimal subset of JNode services to allow us to run JNode commands.
- *
- * @param root the notional JNode sandbox root directory or <code>null</code>.
- * @throws EmuException
- */
- public static void initEnv(File root) throws EmuException {
- if (true) {
- if (root == null) {
- root = new File("").getAbsoluteFile();
- System.err.println("Assuming that the JNode root is '" + root + "'");
- }
- InitialNaming.setNameSpace(new BasicNameSpace());
-
- try {
- InitialNaming.bind(DeviceManager.NAME, DeviceManager.INSTANCE);
- AliasManager aliasMgr =
- new DefaultAliasManager(new DummyExtensionPoint()).createAliasManager();
- SyntaxManager syntaxMgr =
- new DefaultSyntaxManager(new DummyExtensionPoint()).createSyntaxManager();
- for (String pluginName : PLUGIN_NAMES) {
- configurePluginCommands(root, pluginName, aliasMgr, syntaxMgr);
- }
- System.setProperty("jnode.invoker", "thread");
- System.setProperty("jnode.interpreter", "redirecting");
- System.setProperty("jnode.debug", "true");
- InitialNaming.bind(AliasManager.NAME, aliasMgr);
- InitialNaming.bind(ShellManager.NAME, new DefaultShellManager());
- InitialNaming.bind(SyntaxManager.NAME, syntaxMgr);
- InitialNaming.bind(HelpFactory.NAME, new DefaultHelpFactory());
- } catch (NamingException ex) {
- throw new EmuException("Problem setting up InitialNaming bindings", ex);
- }
- }
- }
-
- /**
- * Configure any command classes specified by a given plugin's descriptor
- *
- * @param root the root directory for the JNode sandbox.
- * @param pluginName the plugin to be processed
- * @param aliasMgr the alias manager to be populated
- * @param syntaxMgr the syntax manager to be populated
- * @throws EmuException
- */
- private static void configurePluginCommands(File root, String pluginName, AliasManager aliasMgr,
- SyntaxManager syntaxMgr) throws EmuException {
- XMLElement pluginDescriptor = loadPluginDescriptor(root, pluginName);
- extractAliases(pluginDescriptor, aliasMgr);
- extractSyntaxBundles(pluginDescriptor, syntaxMgr);
- }
-
- /**
- * Populate the supplied syntax manager with syntax entries from a plugin descriptor.
- *
- * @param pluginDescriptor the plugin descriptor's root XML element
- * @param syntaxMgr the syntax manager to be populated.
- * @throws EmuException
- */
- private static void extractSyntaxBundles(XMLElement pluginDescriptor, SyntaxManager syntaxMgr)
- throws EmuException {
- XMLElement syntaxesDescriptor = findExtension(pluginDescriptor, SyntaxManager.SYNTAXES_EP_NAME);
- if (syntaxesDescriptor == null) {
- return;
- }
- SyntaxSpecLoader loader = new SyntaxSpecLoader();
- for (XMLElement syntaxDescriptor : syntaxesDescriptor.getChildren()) {
- if (!syntaxDescriptor.getName().equals("syntax")) {
- continue;
- }
- SyntaxSpecAdapter adaptedElement = new XMLSyntaxSpecAdapter(syntaxDescriptor);
- try {
- SyntaxBundle bundle = loader.loadSyntax(adaptedElement);
- if (bundle != null) {
- syntaxMgr.add(bundle);
- }
- } catch (Exception ex) {
- throw new EmuException("problem in syntax", ex);
- }
- }
- }
-
- /**
- * Populate the supplied alias manager with aliases from a plugin descriptor.
- *
- * @param pluginDescriptor the plugin descriptor's root XML element
- * @param aliasMgr the alias manager to be populated.
- * @throws EmuException
- */
- private static void extractAliases(XMLElement pluginDescriptor, AliasManager aliasMgr) {
- XMLElement aliasesDescriptor = findExtension(pluginDescriptor, AliasManager.ALIASES_EP_NAME);
- if (aliasesDescriptor == null) {
- return;
- }
- for (XMLElement aliasDescriptor : aliasesDescriptor.getChildren()) {
- if (aliasDescriptor.getName().equals("alias")) {
- String alias = aliasDescriptor.getStringAttribute("name");
- String className = aliasDescriptor.getStringAttribute("class");
- aliasMgr.add(alias, className);
- }
- }
- }
-
- /**
- * Locate the descriptor for a given extension point.
- *
- * @param pluginDescriptor the plugin descriptor
- * @param epName the extension point's name
- * @return
- */
- private static XMLElement findExtension(XMLElement pluginDescriptor, String epName) {
- for (XMLElement child : pluginDescriptor.getChildren()) {
- if (child.getName().equals("extension") &&
- epName.equals(child.getStringAttribute("point"))) {
- return child;
- }
- }
- return null;
- }
-
- /**
- * Locate and load a plugin descriptor. We search the "descriptors" directory of
- * each of the projects listed in ALL_PROJECTS
- *
- * @param root the notional root directory for the user's JNode sandbox.
- * @param pluginName the name of the plugin we're trying to locate
- * @return the loaded plugin descriptor or <code>null</code>
- * @throws EmuException
- */
- private static XMLElement loadPluginDescriptor(File root, String pluginName)
- throws EmuException {
- File file = null;
- for (String projectName : ALL_PROJECTS) {
- file = new File(new File(new File(root, projectName), "descriptors"), pluginName + ".xml");
- if (file.exists()) {
- break;
- }
- }
- if (!file.exists()) {
- throw new EmuException("Cannot find plugin descriptor file for '" +
- pluginName + "': " + file.getAbsolutePath());
- }
- BufferedReader br = null;
- try {
- XMLElement elem = new XMLElement();
- br = new BufferedReader(new FileReader(file));
- elem.parseFromReader(br);
- if (!elem.getName().equals("plugin")) {
- throw new EmuException("File does not contain a 'plugin' descriptor: " + file);
- }
- return elem;
- } catch (IOException ex) {
- throw new EmuException("Problem reading / parsing plugin descriptor file " + file, ex);
- } finally {
- try {
- br.close();
- } catch (IOException ex) {
- // ignore
- }
- }
- }
-}
Deleted: trunk/distr/src/emu/org/jnode/emu/EmuException.java
===================================================================
--- trunk/distr/src/emu/org/jnode/emu/EmuException.java 2009-01-18 11:04:39 UTC (rev 4886)
+++ trunk/distr/src/emu/org/jnode/emu/EmuException.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -1,12 +0,0 @@
-package org.jnode.emu;
-
-public class EmuException extends Exception {
-
- public EmuException(String message) {
- super(message);
- }
-
- public EmuException(String message, Throwable cause) {
- super(message, cause);
- }
-}
Modified: trunk/shell/.classpath
===================================================================
--- trunk/shell/.classpath 2009-01-18 11:04:39 UTC (rev 4886)
+++ trunk/shell/.classpath 2009-01-18 13:23:15 UTC (rev 4887)
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/shell"/>
+ <classpathentry kind="src" path="src/emu"/>
<classpathentry kind="src" path="src/test"/>
<classpathentry kind="src" path="/JNode-Core"/>
<classpathentry kind="lib" path="/JNode-Core/lib/log4j-1.2.8.jar"/>
@@ -9,5 +10,6 @@
<classpathentry kind="lib" path="/JNode-Core/lib/ant-launcher.jar"/>
<classpathentry exported="true" kind="lib" path="lib/bsh-2.0b5.jar"/>
<classpathentry kind="lib" path="lib/rhino1.6r5-jsr223.jar"/>
+ <classpathentry kind="lib" path="/JNode-Builder/lib/nanoxml-2.2.3.jar"/>
<classpathentry kind="output" path="build/classes"/>
</classpath>
Modified: trunk/shell/build.xml
===================================================================
--- trunk/shell/build.xml 2009-01-18 11:04:39 UTC (rev 4886)
+++ trunk/shell/build.xml 2009-01-18 13:23:15 UTC (rev 4887)
@@ -28,6 +28,7 @@
<jnode.compile>
<src path="${my-src.dir}/shell"/>
<src path="${my-src.dir}/test"/>
+ <src path="${my-src.dir}/emu"/>
<classpath refid="my-cp"/>
</jnode.compile>
</target>
Modified: trunk/shell/descriptors/org.jnode.test.shell.xml
===================================================================
--- trunk/shell/descriptors/org.jnode.test.shell.xml 2009-01-18 11:04:39 UTC (rev 4886)
+++ trunk/shell/descriptors/org.jnode.test.shell.xml 2009-01-18 13:23:15 UTC (rev 4887)
@@ -20,9 +20,13 @@
<runtime>
<library name="jnode-shell.jar">
<export name="org.jnode.test.shell.*"/>
+ <export name="org.jnode.test.shell.bjorne.*"/>
+ <export name="org.jnode.test.shell.harness.*"/>
<export name="org.jnode.test.shell.help.*"/>
+ <export name="org.jnode.test.shell.proclet.*"/>
+ <export name="org.jnode.test.shell.io.*"/>
+ <export name="org.jnode.test.shell.proclet.*"/>
<export name="org.jnode.test.shell.syntax.*"/>
- <export name="org.jnode.test.shell.proclet.*"/>
</library>
</runtime>
@@ -34,5 +38,6 @@
<extension point="org.jnode.security.permissions">
<permission class="java.lang.RuntimePermission" name="setIO"/>
+ <permission class="java.lang.RuntimePermission" name="exitVM"/>
</extension>
</plugin>
Added: trunk/shell/src/emu/org/jnode/emu/DeviceManager.java
===================================================================
--- trunk/shell/src/emu/org/jnode/emu/DeviceManager.java (rev 0)
+++ trunk/shell/src/emu/org/jnode/emu/DeviceManager.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -0,0 +1,105 @@
+/*
+ * $Id$
+ */
+package org.jnode.emu;
+
+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;
+import org.jnode.driver.DeviceFinder;
+import org.jnode.driver.DeviceToDriverMapper;
+import org.jnode.driver.DriverException;
+
+/**
+ * @author Levente S\u00e1ntha
+ */
+public class DeviceManager extends AbstractDeviceManager {
+ public static final Logger log = Logger.getLogger(DeviceManager.class);
+
+ public static final DeviceManager INSTANCE = new DeviceManager();
+
+ private List<DeviceFinder> finders = new ArrayList<DeviceFinder>();
+
+ private List<DeviceToDriverMapper> mappers = new ArrayList<DeviceToDriverMapper>();
+
+ private DeviceManager() {
+ }
+
+ public void removeAll() {
+ finders.clear();
+ mappers.clear();
+
+ for (Device device : getDevices()) {
+ try {
+ unregister(device);
+ } catch (DriverException e) {
+ log.error("can't unregister " + device);
+ }
+ }
+ }
+
+ public void add(DeviceFinder finder, DeviceToDriverMapper mapper) {
+ boolean doStart = false;
+
+ if (!finders.contains(finder)) {
+ finders.add(finder);
+ doStart = true;
+ }
+
+ if (!mappers.contains(mapper)) {
+ mappers.add(mapper);
+ doStart = true;
+ }
+
+ if (doStart) {
+ start();
+ }
+ }
+
+ /**
+ * Start this manager
+ */
+ public final void start() {
+ // Thread thread = new Thread()
+ // {
+ // public void run()
+ // {
+ log.debug("Loading extensions ...");
+ loadExtensions();
+ log.debug("Extensions loaded !");
+ // }
+ // };
+ // thread.start();
+
+ try {
+ // must be called before findDeviceDrivers
+ log.debug("findDevices ...");
+ findDevices();
+
+ log.debug("findDeviceDrivers ...");
+ findDeviceDrivers();
+
+ log.debug("StubDeviceManager initialized !");
+ } catch (InterruptedException e) {
+ log.fatal("can't find devices", e);
+ }
+ }
+
+ protected final void refreshFinders(List<DeviceFinder> finders) {
+ log.info("refreshFinders");
+ finders.clear();
+ finders.addAll(this.finders);
+ }
+
+ protected final void refreshMappers(List<DeviceToDriverMapper> mappers) {
+ log.info("refreshMappers");
+ mappers.clear();
+ mappers.addAll(this.mappers);
+
+ // Now sort them
+ Collections.sort(mappers, MapperComparator.INSTANCE);
+ }
+}
Added: trunk/shell/src/emu/org/jnode/emu/Emu.java
===================================================================
--- trunk/shell/src/emu/org/jnode/emu/Emu.java (rev 0)
+++ trunk/shell/src/emu/org/jnode/emu/Emu.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -0,0 +1,232 @@
+/*
+ * $Id: NameSpace.java 4564 2008-09-18 22:01:10Z fduminy $
+ *
+ * JNode.org
+ * Copyright (C) 2003-2006 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package org.jnode.emu;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import javax.naming.NamingException;
+
+import org.jnode.emu.naming.BasicNameSpace;
+import org.jnode.emu.plugin.model.DummyExtensionPoint;
+import org.jnode.naming.InitialNaming;
+import org.jnode.nanoxml.XMLElement;
+import org.jnode.shell.ShellManager;
+import org.jnode.shell.alias.AliasManager;
+import org.jnode.shell.alias.def.DefaultAliasManager;
+import org.jnode.shell.def.DefaultShellManager;
+import org.jnode.shell.help.HelpFactory;
+import org.jnode.shell.help.def.DefaultHelpFactory;
+import org.jnode.shell.syntax.DefaultSyntaxManager;
+import org.jnode.shell.syntax.SyntaxBundle;
+import org.jnode.shell.syntax.SyntaxManager;
+import org.jnode.shell.syntax.SyntaxSpecAdapter;
+import org.jnode.shell.syntax.SyntaxSpecLoader;
+import org.jnode.shell.syntax.XMLSyntaxSpecAdapter;
+
+/**
+ * Emu is the core of a light-weight JNode emulator that allows (some) JNode
+ * applications to be run using a classic JVM in the context of a JNode development sandbox.
+ * <p>
+ * An Emu is also a large flightless bird ... which seems kind of appropriate.
+ *
+ * @author Levente S\u00e1ntha
+ * @author Stephen Crawley
+ */
+public abstract class Emu {
+ private static final String[] ALL_PROJECTS = new String[]{
+ "core", "distr", "fs", "gui", "net", "shell", "sound", "textui"
+ };
+
+ // FIXME configuring a hard-coded list of command plugins is a bad idea.
+ private static final String[] PLUGIN_NAMES = new String[]{
+ "org.jnode.shell.command",
+ "org.jnode.shell.command.posix",
+ "org.jnode.shell.command.driver.console",
+ "org.jnode.apps.editor",
+ "org.jnode.apps.edit",
+ "org.jnode.apps.console",
+ };
+
+ /**
+ * Initialize a minimal subset of JNode services to allow us to run JNode commands.
+ *
+ * @param root the notional JNode sandbox root directory or <code>null</code>.
+ * @throws EmuException
+ */
+ public static void initEnv(File root) throws EmuException {
+ if (true) {
+ if (root == null) {
+ root = new File("").getAbsoluteFile();
+ System.err.println("Assuming that the JNode root is '" + root + "'");
+ }
+ InitialNaming.setNameSpace(new BasicNameSpace());
+
+ try {
+ InitialNaming.bind(DeviceManager.NAME, DeviceManager.INSTANCE);
+ AliasManager aliasMgr =
+ new DefaultAliasManager(new DummyExtensionPoint()).createAliasManager();
+ SyntaxManager syntaxMgr =
+ new DefaultSyntaxManager(new DummyExtensionPoint()).createSyntaxManager();
+ for (String pluginName : PLUGIN_NAMES) {
+ configurePluginCommands(root, pluginName, aliasMgr, syntaxMgr);
+ }
+ System.setProperty("jnode.invoker", "thread");
+ System.setProperty("jnode.interpreter", "redirecting");
+ System.setProperty("jnode.debug", "true");
+ InitialNaming.bind(AliasManager.NAME, aliasMgr);
+ InitialNaming.bind(ShellManager.NAME, new DefaultShellManager());
+ InitialNaming.bind(SyntaxManager.NAME, syntaxMgr);
+ InitialNaming.bind(HelpFactory.NAME, new DefaultHelpFactory());
+ } catch (NamingException ex) {
+ throw new EmuException("Problem setting up InitialNaming bindings", ex);
+ }
+ }
+ }
+
+ /**
+ * Configure any command classes specified by a given plugin's descriptor
+ *
+ * @param root the root directory for the JNode sandbox.
+ * @param pluginName the plugin to be processed
+ * @param aliasMgr the alias manager to be populated
+ * @param syntaxMgr the syntax manager to be populated
+ * @throws EmuException
+ */
+ private static void configurePluginCommands(File root, String pluginName, AliasManager aliasMgr,
+ SyntaxManager syntaxMgr) throws EmuException {
+ XMLElement pluginDescriptor = loadPluginDescriptor(root, pluginName);
+ extractAliases(pluginDescriptor, aliasMgr);
+ extractSyntaxBundles(pluginDescriptor, syntaxMgr);
+ }
+
+ /**
+ * Populate the supplied syntax manager with syntax entries from a plugin descriptor.
+ *
+ * @param pluginDescriptor the plugin descriptor's root XML element
+ * @param syntaxMgr the syntax manager to be populated.
+ * @throws EmuException
+ */
+ private static void extractSyntaxBundles(XMLElement pluginDescriptor, SyntaxManager syntaxMgr)
+ throws EmuException {
+ XMLElement syntaxesDescriptor = findExtension(pluginDescriptor, SyntaxManager.SYNTAXES_EP_NAME);
+ if (syntaxesDescriptor == null) {
+ return;
+ }
+ SyntaxSpecLoader loader = new SyntaxSpecLoader();
+ for (XMLElement syntaxDescriptor : syntaxesDescriptor.getChildren()) {
+ if (!syntaxDescriptor.getName().equals("syntax")) {
+ continue;
+ }
+ SyntaxSpecAdapter adaptedElement = new XMLSyntaxSpecAdapter(syntaxDescriptor);
+ try {
+ SyntaxBundle bundle = loader.loadSyntax(adaptedElement);
+ if (bundle != null) {
+ syntaxMgr.add(bundle);
+ }
+ } catch (Exception ex) {
+ throw new EmuException("problem in syntax", ex);
+ }
+ }
+ }
+
+ /**
+ * Populate the supplied alias manager with aliases from a plugin descriptor.
+ *
+ * @param pluginDescriptor the plugin descriptor's root XML element
+ * @param aliasMgr the alias manager to be populated.
+ * @throws EmuException
+ */
+ private static void extractAliases(XMLElement pluginDescriptor, AliasManager aliasMgr) {
+ XMLElement aliasesDescriptor = findExtension(pluginDescriptor, AliasManager.ALIASES_EP_NAME);
+ if (aliasesDescriptor == null) {
+ return;
+ }
+ for (XMLElement aliasDescriptor : aliasesDescriptor.getChildren()) {
+ if (aliasDescriptor.getName().equals("alias")) {
+ String alias = aliasDescriptor.getStringAttribute("name");
+ String className = aliasDescriptor.getStringAttribute("class");
+ aliasMgr.add(alias, className);
+ }
+ }
+ }
+
+ /**
+ * Locate the descriptor for a given extension point.
+ *
+ * @param pluginDescriptor the plugin descriptor
+ * @param epName the extension point's name
+ * @return
+ */
+ private static XMLElement findExtension(XMLElement pluginDescriptor, String epName) {
+ for (XMLElement child : pluginDescriptor.getChildren()) {
+ if (child.getName().equals("extension") &&
+ epName.equals(child.getStringAttribute("point"))) {
+ return child;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Locate and load a plugin descriptor. We search the "descriptors" directory of
+ * each of the projects listed in ALL_PROJECTS
+ *
+ * @param root the notional root directory for the user's JNode sandbox.
+ * @param pluginName the name of the plugin we're trying to locate
+ * @return the loaded plugin descriptor or <code>null</code>
+ * @throws EmuException
+ */
+ private static XMLElement loadPluginDescriptor(File root, String pluginName)
+ throws EmuException {
+ File file = null;
+ for (String projectName : ALL_PROJECTS) {
+ file = new File(new File(new File(root, projectName), "descriptors"), pluginName + ".xml");
+ if (file.exists()) {
+ break;
+ }
+ }
+ if (!file.exists()) {
+ throw new EmuException("Cannot find plugin descriptor file for '" +
+ pluginName + "': " + file.getAbsolutePath());
+ }
+ BufferedReader br = null;
+ try {
+ XMLElement elem = new XMLElement();
+ br = new BufferedReader(new FileReader(file));
+ elem.parseFromReader(br);
+ if (!elem.getName().equals("plugin")) {
+ throw new EmuException("File does not contain a 'plugin' descriptor: " + file);
+ }
+ return elem;
+ } catch (IOException ex) {
+ throw new EmuException("Problem reading / parsing plugin descriptor file " + file, ex);
+ } finally {
+ try {
+ br.close();
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+ }
+}
Added: trunk/shell/src/emu/org/jnode/emu/EmuException.java
===================================================================
--- trunk/shell/src/emu/org/jnode/emu/EmuException.java (rev 0)
+++ trunk/shell/src/emu/org/jnode/emu/EmuException.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -0,0 +1,12 @@
+package org.jnode.emu;
+
+public class EmuException extends Exception {
+
+ public EmuException(String message) {
+ super(message);
+ }
+
+ public EmuException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
Modified: trunk/shell/src/test/org/jnode/test/shell/Cassowary.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/Cassowary.java 2009-01-18 11:04:39 UTC (rev 4886)
+++ trunk/shell/src/test/org/jnode/test/shell/Cassowary.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -34,9 +34,11 @@
import org.jnode.shell.help.def.DefaultHelpFactory;
/**
- * A Cassowary is another large Australian bird ...
+ * This class assembles a minimal set of JNode services to support unit
+ * testing some shell and syntax infrastructure.
+ * <p>
+ * A Cassowary is another large flightless bird ... like an Emu but different.
*
- * @author Levente S\u00e1ntha
* @author cr...@jn...
*/
public class Cassowary {
Added: trunk/shell/src/test/org/jnode/test/shell/command/posix/TrueTest.xml
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/command/posix/TrueTest.xml (rev 0)
+++ trunk/shell/src/test/org/jnode/test/shell/command/posix/TrueTest.xml 2009-01-18 13:23:15 UTC (rev 4887)
@@ -0,0 +1,6 @@
+<testSpec>
+<title>Test 'true'</title>
+<command>org.jnode.shell.command.posix.TrueCommand</command>
+<runMode>AS_ALIAS</runMode>
+<rc>0</rc>
+</testSpec>
\ No newline at end of file
Added: trunk/shell/src/test/org/jnode/test/shell/harness/ClassTestRunner.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/harness/ClassTestRunner.java (rev 0)
+++ trunk/shell/src/test/org/jnode/test/shell/harness/ClassTestRunner.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -0,0 +1,59 @@
+/**
+ *
+ */
+package org.jnode.test.shell.harness;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+
+/**
+ * This TestRunner runs a a class by calling its 'static void main(Sting[])' entry
+ * point. Note that classes that call System.exit(status) are problematic.
+ *
+ * @author cr...@jn...
+ */
+class ClassTestRunner implements TestRunnable {
+
+ private ByteArrayOutputStream outBucket;
+ private ByteArrayOutputStream errBucket;
+
+ private final TestSpecification spec;
+ private final TestHarness harness;
+
+ public ClassTestRunner(TestSpecification spec, TestHarness harness) {
+ this.spec = spec;
+ this.harness = harness;
+ }
+
+ @Override
+ public int run() throws Exception {
+ Class<?> commandClass = Class.forName(spec.getCommand());
+ Method method = commandClass.getMethod("main", String[].class);
+ String[] args = spec.getArgs().toArray(new String[0]);
+ method.invoke(null, (Object) args);
+ return check() ? 0 : 1;
+ }
+
+ private boolean check() {
+ // When a class is run this way we cannot capture the RC.
+ return
+ harness.expect(outBucket.toString(), spec.getOutputContent(), "output content") &&
+ harness.expect(errBucket.toString(), spec.getErrorContent(), "err content");
+ }
+
+ @Override
+ public void cleanup() {
+ }
+
+ @Override
+ public void setup() {
+ System.setIn(new ByteArrayInputStream(spec.getInputContent().getBytes()));
+ outBucket = new ByteArrayOutputStream();
+ errBucket = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(outBucket));
+ System.setErr(new PrintStream(errBucket));
+ }
+
+}
\ No newline at end of file
Added: trunk/shell/src/test/org/jnode/test/shell/harness/CommandTestRunner.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/harness/CommandTestRunner.java (rev 0)
+++ trunk/shell/src/test/org/jnode/test/shell/harness/CommandTestRunner.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -0,0 +1,121 @@
+/**
+ *
+ */
+package org.jnode.test.shell.harness;
+
+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;
+import org.jnode.shell.CommandLine;
+import org.jnode.shell.CommandShell;
+import org.jnode.shell.ShellUtils;
+import org.jnode.shell.ThreadCommandInvoker;
+import org.jnode.shell.alias.AliasManager;
+import org.jnode.shell.alias.NoSuchAliasException;
+
+
+/**
+ * This TestRunner runs a a class by calling its 'static void main(Sting[])' entry
+ * point. Note that classes that call System.exit(status) are problematic.
+ *
+ * @author cr...@jn...
+ */
+class CommandTestRunner implements TestRunnable {
+
+ private ByteArrayOutputStream outBucket;
+ private ByteArrayOutputStream errBucket;
+
+ private final TestSpecification spec;
+ private final TestHarness harness;
+
+ @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());
+ }
+
+ 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]);
+ AliasManager aliasMgr = ShellUtils.getAliasManager();
+ CommandInvoker invoker = new ThreadCommandInvoker(shell);
+ CommandLine cmdLine = new CommandLine(spec.getCommand(), args);
+ CommandInfo cmdInfo;
+ try {
+ Class<?> cls = aliasMgr.getAliasClass(spec.getCommand());
+ cmdInfo = new CommandInfo(cls, aliasMgr.isInternal(spec.getCommand()));
+ } catch (NoSuchAliasException ex) {
+ final ClassLoader cl =
+ Thread.currentThread().getContextClassLoader();
+ cmdInfo = new CommandInfo(cl.loadClass(spec.getCommand()), false);
+ }
+ invoker.invoke(cmdLine, cmdInfo);
+ return check() ? 0 : 1;
+ }
+
+ private boolean check() {
+ // When a class is run this way we cannot capture the RC.
+ return
+ harness.expect(outBucket.toString(), spec.getOutputContent(), "output content") &&
+ harness.expect(errBucket.toString(), spec.getErrorContent(), "err content");
+ }
+
+ @Override
+ public void cleanup() {
+ }
+
+ @Override
+ public void setup() {
+ System.setIn(new ByteArrayInputStream(spec.getInputContent().getBytes()));
+ outBucket = new ByteArrayOutputStream();
+ errBucket = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(outBucket));
+ System.setErr(new PrintStream(errBucket));
+ }
+
+}
\ No newline at end of file
Added: trunk/shell/src/test/org/jnode/test/shell/harness/Test.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/harness/Test.java (rev 0)
+++ trunk/shell/src/test/org/jnode/test/shell/harness/Test.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -0,0 +1,16 @@
+package org.jnode.test.shell.harness;
+
+public class Test {
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ if (args.length == 0) {
+ System.out.println("Hi mum");
+ } else if (args[0].equals("System.exit")) {
+ System.exit(1);
+ }
+ }
+
+}
Added: trunk/shell/src/test/org/jnode/test/shell/harness/TestHarness.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/harness/TestHarness.java (rev 0)
+++ trunk/shell/src/test/org/jnode/test/shell/harness/TestHarness.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -0,0 +1,219 @@
+package org.jnode.test.shell.harness;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import net.n3.nanoxml.XMLException;
+
+/**
+ * This is the entry point class for the command test harness. Its
+ * purpose is to run 'black box' tests on commands and the like.
+ *
+ * @author crawley@jnode
+ */
+public class TestHarness {
+
+ private final String commandName = this.getClass().getCanonicalName();
+
+ String[] TESTS = new String[] {
+ "<testSpec>" +
+ "<title>Hi mum</title>" +
+ "<command>org.jnode.test.shell.harness.Test</command>" +
+ "<output>Hi mum\n</output>" +
+ "</testSpec>",
+// "<testSpec>" +
+// "<title>exit</title>" +
+// "<command>org.jnode.test.shell.harness.Test</command>" +
+// "<args><arg>System.exit</arg></args>" +
+// "</testSpec>"
+ };
+
+ private final String[] args;
+
+ private PrintWriter reportWriter;
+ private int testCount;
+ private int errorCount;
+ private int failureCount;
+ private TestSpecification spec = null;
+ private InputStream savedIn;
+ private PrintStream savedOut;
+ private PrintStream savedErr;
+
+ private boolean verbose;
+
+ public TestHarness(String[] args) {
+ this.args = args;
+ this.reportWriter = new PrintWriter(System.err);
+ }
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) throws Exception {
+ new TestHarness(args).run();
+ }
+
+ private void run() throws Exception {
+ if (args.length == 0) {
+ for (String test : TESTS) {
+ try {
+ InputStream is = new ByteArrayInputStream(test.getBytes());
+ spec = new TestSpecification().load(is);
+ execute(spec);
+ } catch (Exception ex) {
+ diagnose(ex, "<built-in-tests>");
+ }
+ }
+ } else if (args[0].equals("--package")) {
+ if (args.length != 2) {
+ usage();
+ }
+ InputStream is = null;
+ try {
+ is = this.getClass().getResourceAsStream(args[1]);
+ spec = new TestSpecification().load(is);
+ execute(spec);
+ } catch (Exception ex) {
+ diagnose(ex, args[1]);
+ }
+ finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+ }
+ } else if (args[0].startsWith("-")) {
+ System.err.println("Unrecognized option '" + args[0] + "'");
+ usage();
+ return;
+ } else {
+ for (String arg : args) {
+ File file = new File(arg);
+ InputStream is = null;
+ try {
+ is = new FileInputStream(file);
+ spec = new TestSpecification().load(is);
+ execute(spec);
+ } catch (Exception ex) {
+ diagnose(ex, arg);
+ }
+ finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+ }
+ }
+ }
+ report("Ran " + testCount + " tests with " + errorCount +
+ " errors and " + failureCount + " failures");
+ }
+
+ private void usage() {
+ System.err.println(commandName + " // run tests from builtin specs");
+ System.err.println(commandName + " --package <java-package> // run tests from specs on classpath");
+ System.err.println(commandName + " <spec-file> ... // run tests from specs read from file system");
+ }
+
+ private void execute(TestSpecification spec) {
+ reportVerbose("Running test '" + spec.getTitle() + "'");
+ testCount++;
+ try {
+ TestRunnable runner;
+ switch (spec.getRunMode()) {
+ case AS_CLASS:
+ runner = new ClassTestRunner(spec, this);
+ break;
+ case AS_ALIAS:
+ runner = new CommandTestRunner(spec, this);
+ break;
+ default:
+ reportVerbose("Run mode '" + spec.getRunMode() + "' not implemented");
+ return;
+ }
+ try {
+ setup();
+ runner.setup();
+ errorCount += runner.run();
+ } finally {
+ runner.cleanup();
+ cleanup();
+ }
+ } catch (Throwable ex) {
+ ex.printStackTrace(reportWriter);
+ failureCount++;
+ }
+ reportVerbose("Completed test '" + spec.getTitle() + "'");
+ }
+
+ private void diagnose(Exception ex, String fileName) throws Exception {
+ if (ex instanceof IOException) {
+ report("IO error while reading test specification: " + ex.getMessage());
+ } else if (ex instanceof XMLException) {
+ String msg = ex.getMessage();
+ if (msg.equals("Nested Exception")) {
+ msg = ((XMLException) ex).getException().getMessage();
+ }
+ report("XML error in test specification '" + fileName + "' : " + msg);
+ } else if (ex instanceof TestSpecificationException) {
+ report("Invalid test specification '" + fileName + ": " + ex.getMessage());
+ } else {
+ throw ex;
+ }
+ }
+
+ /**
+ * Restore the system system streams
+ */
+ private void cleanup() {
+ System.setIn(savedIn);
+ System.setOut(savedOut);
+ System.setErr(savedErr);
+ }
+
+ /**
+ * Save the System streams so that they can be restored.
+ */
+ private void setup() {
+ savedIn = System.in;
+ savedOut = System.out;
+ savedErr = System.err;
+ }
+
+ public void report(String message) {
+ reportWriter.println(message);
+ reportWriter.flush();
+ }
+
+ public void reportVerbose(String message) {
+ if (verbose) {
+ report(message);
+ }
+ }
+
+ public boolean expect(Object expected, Object actual, String desc) {
+ if (expected.equals(actual)) {
+ return true;
+ }
+ report("Incorrect test result for '" + desc + "' in test '" + spec.getTitle() + "'");
+ report(" expected '" + expected + "': got '" + actual + "'");
+ return false;
+ }
+
+ public File getRoot() {
+ // FIXME ... this should be the workspace root.
+ return new File("..");
+ }
+
+}
Added: trunk/shell/src/test/org/jnode/test/shell/harness/TestRunnable.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/harness/TestRunnable.java (rev 0)
+++ trunk/shell/src/test/org/jnode/test/shell/harness/TestRunnable.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -0,0 +1,18 @@
+package org.jnode.test.shell.harness;
+
+/**
+ * This is the API implemented by the command test runners. We cannot
+ * use / extend Runnable because we need to propagate any exceptions
+ * in the {@link TestRunnable.run()} method.
+ *
+ * @author stephen
+ */
+public interface TestRunnable {
+
+ public int run() throws Exception;
+
+ public void setup();
+
+ public void cleanup();
+
+}
Added: trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecification.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecification.java (rev 0)
+++ trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecification.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -0,0 +1,157 @@
+package org.jnode.test.shell.harness;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.n3.nanoxml.IXMLElement;
+import net.n3.nanoxml.IXMLParser;
+import net.n3.nanoxml.StdXMLReader;
+import net.n3.nanoxml.XMLParserFactory;
+
+/**
+ * This represents a command test specification for a command or script.
+ *
+ * @author crawley@jnode
+ */
+public class TestSpecification {
+
+ public static enum RunMode {
+ AS_SCRIPT,
+ AS_CLASS,
+ AS_ALIAS
+ }
+
+ private RunMode runMode;
+ private String command;
+ private List<String> args = new ArrayList<String>();
+ private String inputContent;
+ private String outputContent;
+ private String errorContent;
+ private String title;
+ private int rc;
+ private Map<File, String> fileMap = new HashMap<File, String>();
+
+ private IXMLElement root;
+
+ public TestSpecification() {
+ super();
+ }
+
+ public TestSpecification load(InputStream in) throws Exception {
+ StdXMLReader xr = new StdXMLReader(in);
+ IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
+ parser.setReader(xr);
+ root = (IXMLElement) parser.parse();
+ if (!root.getName().equals("testSpec")) {
+ throw new TestSpecificationException(
+ "The root element should be 'testSpec' not '" + root.getName() + "'");
+ }
+ runMode = RunMode.valueOf(extractElementValue("runMode", "AS_CLASS"));
+ title = extractElementValue("title");
+ command = extractElementValue("command");
+ inputContent = extractElementValue("input", "");
+ outputContent = extractElementValue("output", "");
+ errorContent = extractElementValue("error", "");
+ try {
+ rc = Integer.parseInt(extractElementValue("error", "0").trim());
+ } catch (NumberFormatException ex) {
+ throw new TestSpecificationException("'rc' is not an integer");
+ }
+ IXMLElement elem = root.getFirstChildNamed("args");
+ if (elem != null) {
+ for (Object obj : elem.getChildren()) {
+ if (obj instanceof IXMLElement) {
+ IXMLElement child = (IXMLElement) obj;
+ if (!child.getName().equals("arg")) {
+ throw new TestSpecificationException(
+ "Child elements of 'args' should be 'arg' not '" + root.getName() + "'");
+ }
+ args.add(child.getContent());
+ }
+ }
+ }
+ elem = root.getFirstChildNamed("files");
+ if (elem != null) {
+ for (Object obj : elem.getChildren()) {
+ if (obj instanceof IXMLElement) {
+ IXMLElement child = (IXMLElement) obj;
+ if (!child.getName().equals("file")) {
+ throw new TestSpecificationException(
+ "Child elements of 'files' should be 'file' not '" + root.getName() + "'");
+ }
+ String fileName = extractElementValue(child, "name");
+ String content = extractElementValue(child, "content", "");
+ fileMap.put(new File(fileName), content);
+ }
+ }
+ }
+ return this;
+ }
+
+ 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();
+ }
+ }
+
+ private String extractElementValue(IXMLElement parent, String name, String dflt) {
+ IXMLElement elem = parent.getFirstChildNamed(name);
+ return elem == null ? dflt : elem.getContent();
+ }
+
+ private String extractElementValue(String name) throws TestSpecificationException {
+ return extractElementValue(root, name);
+ }
+
+ private String extractElementValue(String name, String dflt) {
+ return extractElementValue(root, name, dflt);
+ }
+
+ public String getOutputContent() {
+ return outputContent;
+ }
+
+ public String getErrorContent() {
+ return errorContent;
+ }
+
+ public int getRc() {
+ return rc;
+ }
+
+ public void addFile(File file, String content) {
+ fileMap.put(file, content);
+ }
+
+ public Map<File, String> getFileMap() {
+ return fileMap;
+ }
+
+ public RunMode getRunMode() {
+ return runMode;
+ }
+
+ public String getCommand() {
+ return command;
+ }
+
+ public List<String> getArgs() {
+ return args;
+ }
+
+ public String getInputContent() {
+ return inputContent;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+}
Added: trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecificationException.java
===================================================================
--- trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecificationException.java (rev 0)
+++ trunk/shell/src/test/org/jnode/test/shell/harness/TestSpecificationException.java 2009-01-18 13:23:15 UTC (rev 4887)
@@ -0,0 +1,11 @@
+package org.jnode.test.shell.harness;
+
+public class TestSpecificationException extends Exception {
+
+ private static final long serialVersionUID = -6276556804636413362L;
+
+ public TestSpecificationException(String message) {
+ super(message);
+ }
+
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|