/* * $Id$ * * Copyright (C) 2003-2015 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.test.shell.harness; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import org.jnode.naming.InitialNaming; import org.jnode.plugin.PluginManager; import org.jnode.plugin.PluginReference; import org.jnode.plugin.PluginRegistry; import org.jnode.shell.CommandShell; import org.jnode.shell.ShellException; import org.jnode.test.shell.harness.TestSpecification.FileSpecification; import org.jnode.util.ProxyStream; import org.jnode.util.Version; /** * This base class supplies functions for getting hold of "the shell" for * testing commands, configuring required plugins and setting up the * System streams for a command. * * @author crawley@jnode.org */ public abstract class TestRunnerBase implements TestRunnable { private class TeeStream extends FilterOutputStream { private OutputStream out2; public TeeStream(OutputStream out, OutputStream out2) { super(out); this.out2 = out2; } @Override public void close() throws IOException { super.close(); out2.close(); } @Override public void flush() throws IOException { super.flush(); out2.flush(); } @Override public void write(int b) throws IOException { super.write(b); out2.write(b); } } protected ByteArrayOutputStream outBucket; protected ByteArrayOutputStream errBucket; protected final TestSpecification spec; protected final TestHarness harness; protected final boolean usingEmu; public TestRunnerBase(TestSpecification spec, TestHarness harness) { super(); this.spec = spec; this.harness = harness; this.usingEmu = TestEmu.initEmu(harness.getRoot()); } public CommandShell getShell() throws ShellException { CommandShell shell = new TestCommandShell(System.in, System.out, System.err); shell.configureShell(); return shell; } @Override public void cleanup() { if (!harness.preserveTempFiles()) { for (FileSpecification fs : spec.getFiles()) { File f = harness.tempFile(fs.getFile()); if (f.isFile()) { f.delete(); } else if (f.isDirectory()) { harness.cleanDir(f); f.delete(); } } } } @SuppressWarnings("unchecked") @Override public void setup() throws IOException, TestRunnerException { ensurePluginsLoaded(spec.getTestSet()); for (PluginSpecification plugin : spec.getPlugins()) { ensurePluginLoaded(plugin); } System.setIn(new ByteArrayInputStream(spec.getInputContent().toString().getBytes())); outBucket = new ByteArrayOutputStream(); errBucket = new ByteArrayOutputStream(); OutputStream out, err; if (harness.isDebug()) { if (System.out instanceof ProxyStream<?>) { out = ((ProxyStream<PrintStream>) System.out).getProxiedStream(); err = ((ProxyStream<PrintStream>) System.err).getProxiedStream(); } else { out = System.out; err = System.err; } out = new TeeStream(outBucket, out); err = new TeeStream(errBucket, err); } else { out = outBucket; err = errBucket; } System.setOut(new PrintStream(out)); System.setErr(new PrintStream(err)); for (FileSpecification fs : spec.getFiles()) { File f = harness.tempFile(fs.getFile()); if (fs.isInput()) { if (fs.isDirectory()) { f.mkdirs(); } else { f.getParentFile().mkdirs(); OutputStream os = new FileOutputStream(f); try { byte[] bytes = fs.getFileContent().getBytes(); os.write(bytes); } finally { os.close(); } } } } } protected void flush() { System.out.flush(); System.err.flush(); } protected boolean checkFiles() throws IOException { boolean ok = true; for (FileSpecification fs : spec.getFiles()) { File f = harness.tempFile(fs.getFile()); if (!fs.isInput()) { if (fs.isDirectory()) { if (!f.exists()) { harness.fail("directory not created: '" + f + "'"); ok = false; } else if (!f.isDirectory()) { harness.fail("object created is not a directory: '" + f + "'"); ok = false; } } else { if (!f.exists()) { harness.fail("file not created: '" + f + "'"); ok = false; } else if (!f.isFile()) { harness.fail("object created is not a file: '" + f + "'"); ok = false; } else { int fileLength = (int) f.length(); byte[] bytes = new byte[fileLength]; InputStream is = new FileInputStream(f); try { is.read(bytes); } finally { is.close(); } String content = new String(bytes); ok = ok & harness.expect( content, fs.getFileContent(), "file content (" + f + ")"); } } } } return ok; } private void ensurePluginsLoaded(TestSetSpecification testSet) throws TestRunnerException { if (testSet == null) { return; } ensurePluginsLoaded(testSet.getParentSet()); for (PluginSpecification plugin : spec.getTestSet().getPlugins()) { ensurePluginLoaded(plugin); } } protected void ensurePluginLoaded(PluginSpecification plugin) throws TestRunnerException { String id = plugin.getPluginId(); if (usingEmu) { TestEmu.loadPseudoPlugin(id, plugin.getClassName()); } else { String ver = (plugin.getPluginVersion().length() == 0) ? System.getProperty("os.version") : plugin.getPluginVersion(); try { PluginManager mgr = InitialNaming.lookup(PluginManager.NAME); PluginRegistry reg = mgr.getRegistry(); if (reg.getPluginDescriptor(id) == null) { reg.loadPlugin(mgr.getLoaderManager(), new PluginReference(id, new Version(ver)), true); } } catch (Exception ex) { System.out.println(ex.getMessage()); throw new TestRunnerException( "Cannot load plugin '" + plugin.getPluginId() + "/" + ver + "'", ex); } } } }