/*
* Copyright (c) 2005, Rob Gordon.
*/
package org.oddjob;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Properties;
import junit.framework.TestCase;
import org.apache.log4j.Logger;
import org.oddjob.arooa.ArooaException;
import org.oddjob.arooa.ArooaParseException;
import org.oddjob.arooa.ArooaSession;
import org.oddjob.arooa.ComponentTrinity;
import org.oddjob.arooa.parsing.MockArooaContext;
import org.oddjob.arooa.registry.BeanDirectory;
import org.oddjob.arooa.registry.ComponentPool;
import org.oddjob.arooa.runtime.MockRuntimeConfiguration;
import org.oddjob.arooa.runtime.RuntimeConfiguration;
import org.oddjob.arooa.types.XMLConfigurationType;
import org.oddjob.arooa.xml.XMLConfiguration;
import org.oddjob.input.InputHandler;
import org.oddjob.input.InputRequest;
import org.oddjob.jobs.EchoJob;
import org.oddjob.state.JobState;
import org.oddjob.state.ParentState;
import org.oddjob.structural.StructuralEvent;
import org.oddjob.structural.StructuralListener;
import org.oddjob.tools.ConsoleCapture;
import org.oddjob.tools.OurDirs;
import org.oddjob.tools.StateSteps;
/**
*
* @author Rob Gordon.
*/
public class OddjobTest extends TestCase {
private static final Logger logger = Logger.getLogger(OddjobTest.class);
/**
* Test resetting Oddjob
*
*/
public void testReset() {
class MyStructuralListener implements StructuralListener {
int count;
public void childAdded(StructuralEvent event) {
count++;
}
public void childRemoved(StructuralEvent event) {
count--;
}
}
String xml =
"<oddjob xmlns:state='http://rgordon.co.uk/oddjob/state'>" +
" <job>" +
" <state:flag id='flag' state='COMPLETE'/>" +
" </job>" +
"</oddjob>";
Oddjob oj = new Oddjob();
oj.setConfiguration(new XMLConfiguration("XML", xml));
StateSteps ojSteps = new StateSteps(oj);
ojSteps.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.COMPLETE);
MyStructuralListener childListener = new MyStructuralListener();
oj.addStructuralListener(childListener);
assertEquals(0, childListener.count);
oj.run();
assertEquals(1, childListener.count);
ojSteps.checkNow();
Stateful flag = (Stateful) new OddjobLookup(oj).lookup("flag");
StateSteps flagSteps = new StateSteps(flag);
flagSteps.startCheck(JobState.COMPLETE);
flagSteps.checkNow();
flagSteps.startCheck(JobState.COMPLETE, JobState.READY,
JobState.DESTROYED);
ojSteps.startCheck(ParentState.COMPLETE, ParentState.READY);
oj.hardReset();
flagSteps.checkNow();
ojSteps.checkNow();
ojSteps.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.COMPLETE);
oj.run();
ojSteps.checkNow();
ojSteps.startCheck(ParentState.COMPLETE, ParentState.READY);
oj.hardReset();
ojSteps.checkNow();
ojSteps.startCheck(ParentState.READY, ParentState.EXECUTING,
ParentState.COMPLETE);
oj.run();
ojSteps.checkNow();
ojSteps.startCheck(ParentState.COMPLETE, ParentState.DESTROYED);
oj.destroy();
}
/**
* Test reseting Oddjob
*
*/
public void testSoftReset() {
class MyL implements StructuralListener {
int count;
public void childAdded(StructuralEvent event) {
count++;
}
public void childRemoved(StructuralEvent event) {
count--;
}
}
String xml =
"<oddjob xmlns:state='http://rgordon.co.uk/oddjob/state'>" +
" <job>" +
" <state:flag state='INCOMPLETE'/>" +
" </job>" +
"</oddjob>";
Oddjob oj = new Oddjob();
oj.setConfiguration(new XMLConfiguration("XML", xml));
MyL l = new MyL();
oj.addStructuralListener(l);
assertEquals(0, l.count);
oj.run();
assertEquals(1, l.count);
assertEquals(ParentState.INCOMPLETE, oj.lastStateEvent().getState());
oj.softReset();
assertEquals(1, l.count);
assertEquals(ParentState.READY, oj.lastStateEvent().getState());
oj.run();
assertEquals(1, l.count);
assertEquals(ParentState.INCOMPLETE, oj.lastStateEvent().getState());
oj.softReset();
assertEquals(1, l.count);
assertEquals(ParentState.READY, oj.lastStateEvent().getState());
oj.run();
assertEquals(1, l.count);
assertEquals(ParentState.INCOMPLETE, oj.lastStateEvent().getState());
oj.destroy();
}
/**
* Test Oddjob can be rerun after a configuration
* failure using a soft reset.
*
*/
public void testSoftResetOnFailure() {
String xml =
"<oddjob>" +
" <job>" +
" <idontexist/>" +
" </job>" +
"</oddjob>";
Oddjob oj = new Oddjob();
oj.setConfiguration(new XMLConfiguration("XML", xml));
oj.run();
assertEquals(ParentState.EXCEPTION, oj.lastStateEvent().getState());
String xml2 =
"<oddjob xmlns:state='http://rgordon.co.uk/oddjob/state'>" +
" <job>" +
" <state:flag state='COMPLETE'/>" +
" </job>" +
"</oddjob>";
oj.setConfiguration(new XMLConfiguration("XML", xml2));
oj.softReset();
assertEquals(ParentState.READY, oj.lastStateEvent().getState());
oj.run();
assertEquals(ParentState.COMPLETE, oj.lastStateEvent().getState());
oj.destroy();
}
/**
* Test loading an Oddjob without a child.
* @throws ArooaParseException
*
*/
public void testLoadNoChild() throws ArooaParseException {
String config = "<oddjob id='this'/>";
Oddjob test = new Oddjob();
test.setConfiguration(new XMLConfiguration("XML", config));
test.run();
Object root = new OddjobLookup(test).lookup("this");
assertEquals(Oddjob.OddjobRoot.class, root.getClass());
assertEquals(ParentState.READY, test.lastStateEvent().getState());
test.hardReset();
test.run();
assertEquals(ParentState.READY, test.lastStateEvent().getState());
test.destroy();
}
public void testLoadOddjobClassloader() {
String config =
"<oddjob>" +
" <job>" +
" <oddjob id='nested'>" +
" <classLoader>" +
" <url-class-loader>" +
" <files>" +
" <files files='build/*.jar'/>" +
" </files>" +
" </url-class-loader>" +
" </classLoader>" +
" </oddjob>" +
" </job>" +
"</oddjob>";
Oddjob oj = new Oddjob();
oj.setConfiguration(new XMLConfiguration("XML", config));
oj.load();
String nestedConf = "<oddjob/>";
Oddjob test = (Oddjob) new OddjobLookup(oj).lookup("nested");
oj.setConfiguration(new XMLConfiguration("TEST", nestedConf));
test.run();
assertNotNull("Nested classloader",
test.getClassLoader());
oj.destroy();
}
/**
* Test a nested lookup.
* @throws Exception
*/
public void testLookup() throws Exception {
String config =
"<oddjob id='this'>" +
" <job>" +
" <oddjob id='nested'>" +
" <configuration>" +
" <value value='${inner-config}'/>" +
" </configuration>" +
" </oddjob>" +
" </job>" +
"</oddjob>";
String nested =
"<oddjob>" +
" <job>" +
" <variables id='fruits'>" +
" <fruit>" +
" <value value='apple'/>" +
" </fruit>" +
" </variables>" +
" </job>" +
"</oddjob>";
Oddjob oj = new Oddjob();
oj.setConfiguration(new XMLConfiguration("XML", config));
XMLConfigurationType configType = new XMLConfigurationType();
configType.setXml(nested);
oj.setExport("inner-config", configType);
oj.run();
String fruit = new OddjobLookup(oj).lookup(
"nested/fruits.fruit", String.class);
assertEquals("apple", fruit);
oj.destroy();
}
public void testArgs() throws Exception {
String config =
"<oddjob id='this'>" +
" <job>" +
" <variables id='fruits'>" +
" <fruit>" +
" <value value='${this.args[0]}'/>" +
" </fruit>" +
" </variables>" +
" </job>" +
"</oddjob>";
Oddjob test = new Oddjob();
test.setConfiguration(new XMLConfiguration("XML", config));
// Test without arg.
test.run();
assertEquals(ParentState.COMPLETE, test.lastStateEvent().getState());
OddjobLookup lookup = new OddjobLookup(test);
String fruit = lookup.lookup("fruits.fruit", String.class);
assertEquals(null, fruit);
test.hardReset();
// And with arg.
test.setArgs(new String[] { "apple" });
test.run();
fruit = lookup.lookup("fruits.fruit", String.class);
assertEquals("apple", fruit);
test.destroy();
}
private class OurInputHandler implements InputHandler {
@Override
public Properties handleInput(InputRequest[] requests) {
Properties properties = new Properties();
properties.setProperty("our.file.name", "Fruit.txt");
return properties;
}
}
public void testOptionalArgumentExample() {
Oddjob oddjob = new Oddjob();
oddjob.setConfiguration(new XMLConfiguration(
"org/oddjob/OptionalFileNameArg.xml",
getClass().getClassLoader()));
oddjob.setInputHandler(new OurInputHandler());
ConsoleCapture console = new ConsoleCapture();
try (ConsoleCapture.Close close = console.captureConsole()) {
oddjob.run();
oddjob.hardReset();
oddjob.setArgs(new String[] { "Pizzas.txt" } );
oddjob.run();
}
console.dump(logger);
String[] lines = console.getLines();
assertEquals("File Name is Fruit.txt", lines[0].trim());
assertEquals("File Name is Pizzas.txt", lines[1].trim());
assertEquals(2, lines.length);
oddjob.destroy();
}
public void testInheritedProperties() throws Exception {
String config =
"<oddjob>" +
" <job>" +
" <sequential>" +
" <jobs>" +
" <properties>" +
" <values>" +
" <value key='fruit' value='apple'/>" +
" </values>" +
" </properties>" +
" <oddjob id='nested'>" +
" <configuration>" +
" <arooa:configuration xmlns:arooa='http://rgordon.co.uk/oddjob/arooa'>" +
" <xml>" +
" <xml>" +
"<oddjob>" +
" <job>" +
" <variables id='fruits'>" +
" <fruit>" +
" <value value='${fruit}'/>" +
" </fruit>" +
" </variables>" +
" </job>" +
"</oddjob>" +
" </xml>" +
" </xml>" +
" </arooa:configuration>" +
" </configuration>" +
" </oddjob>" +
" </jobs>" +
" </sequential>" +
" </job>" +
"</oddjob>";
Oddjob oj = new Oddjob();
oj.setConfiguration(new XMLConfiguration("XML", config));
oj.run();
String fruit = new OddjobLookup(oj).lookup(
"nested/fruits.fruit", String.class);
assertEquals("apple", fruit);
oj.destroy();
}
/**
* Test Oddjob dir property.
*
*/
public void testDir() {
OurDirs dirs = new OurDirs();
File testFile = dirs.relative("work/xyz.xml");
Oddjob oj = new Oddjob();
oj.setFile(testFile);
assertEquals(dirs.relative("work"), oj.getDir());
oj.destroy();
}
/**
* Test Component Registry management. Test Oddjob
* adds and clears up it's children OK.
* @throws ArooaParseException
*
*/
public void testRegistryManagement() throws ArooaParseException {
final ArooaSession session = new OddjobSessionFactory().createSession();
class OurContext extends MockArooaContext {
@Override
public ArooaSession getSession() {
return session;
}
@Override
public RuntimeConfiguration getRuntime() {
return new MockRuntimeConfiguration() {
@Override
public void configure() throws ArooaException {
}
};
}
}
Oddjob oj = new Oddjob();
oj.setArooaSession(session);
ComponentPool pool = session.getComponentPool();
pool.registerComponent(
new ComponentTrinity(
oj, oj, new OurContext())
, "oj");
String xml =
"<oddjob>" +
" <job>" +
" <echo id='echo'>Hello</echo>" +
" </job>" +
"</oddjob>";
oj.setConfiguration(new XMLConfiguration("XML", xml));
BeanDirectory dir = session.getBeanRegistry();
assertEquals(null, dir.lookup("oj/echo"));
oj.run();
assertNotNull(dir.lookup("oj/echo"));
oj.hardReset();
assertEquals(null, dir.lookup("oj/echo"));
oj.run();
assertNotNull(dir.lookup("oj/echo"));
oj.destroy();
}
public void testCreateFile() throws FileNotFoundException {
OurDirs dirs = new OurDirs();
File testFile = dirs.relative("work/OddjobCreateFileTest.xml");
EchoJob echo = new EchoJob();
echo.setOutput(new FileOutputStream(testFile));
echo.setText("<oddjob/>");
echo.run();
String xml =
"<oddjob>" +
" <job>" +
" <oddjob file='" + testFile.getAbsolutePath() + "'/>" +
" </job>" +
"</oddjob>";
Oddjob oddjob = new Oddjob();
oddjob.setConfiguration(new XMLConfiguration("XML", xml));
oddjob.run();
assertEquals(ParentState.READY, oddjob.lastStateEvent().getState());
testFile.delete();
oddjob.hardReset();
oddjob.run();
assertEquals(ParentState.READY, oddjob.lastStateEvent().getState());
assertTrue(testFile.exists());
}
}