OPEN - BATCH-152: Add facility for calling system commands via a Tasklet

added SystemCommandTasklet to samples (example usage in taskletJob)
This commit is contained in:
robokaso
2008-05-14 12:23:14 +00:00
parent 4a9e02cda6
commit b8cfd7339d
9 changed files with 512 additions and 9 deletions

View File

@@ -0,0 +1,69 @@
package org.springframework.batch.sample.tasklet;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import junit.framework.TestCase;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.sample.tasklet.ConfigurableSystemProcessExitCodeMapper;
/**
* Tests for {@link ConfigurableSystemProcessExitCodeMapper}
*/
public class ConfigurableSystemProcessExitCodeMapperTests extends TestCase {
private ConfigurableSystemProcessExitCodeMapper mapper = new ConfigurableSystemProcessExitCodeMapper();
/**
* Regular usage scenario - mapping adheres to injected values
*/
public void testMapping() {
Map mappings = new HashMap() {{
put(new Integer(0), ExitStatus.FINISHED);
put(new Integer(1), ExitStatus.FAILED);
put(new Integer(2), ExitStatus.CONTINUABLE);
put(new Integer(3), ExitStatus.NOOP);
put(new Integer(4), ExitStatus.UNKNOWN);
put(ConfigurableSystemProcessExitCodeMapper.ELSE_KEY, ExitStatus.UNKNOWN);
}};
mapper.setMappings(mappings);
//check explicitly defined values
for (Iterator iterator = mappings.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
if (entry.getKey().equals(ConfigurableSystemProcessExitCodeMapper.ELSE_KEY)) continue;
int exitCode = ((Integer)entry.getKey()).intValue();
assertSame(entry.getValue(), mapper.getExitStatus(exitCode));
}
//check the else clause
assertSame(mappings.get(ConfigurableSystemProcessExitCodeMapper.ELSE_KEY),
mapper.getExitStatus(5));
}
/**
* Else clause is required in the injected map - setter checks its presence.
*/
public void testSetMappingsMissingElseClause() {
Map missingElse = Collections.EMPTY_MAP;
try {
mapper.setMappings(missingElse);
fail();
}
catch (IllegalArgumentException e) {
// expected
}
Map containsElse = new HashMap() {{
put(ConfigurableSystemProcessExitCodeMapper.ELSE_KEY, ExitStatus.FAILED);
}};
// no error expected now
mapper.setMappings(containsElse);
}
}

View File

@@ -0,0 +1,24 @@
package org.springframework.batch.sample.tasklet;
import junit.framework.TestCase;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.sample.tasklet.SimpleSystemProcessExitCodeMapper;
/**
* Tests for {@link SimpleSystemProcessExitCodeMapper}.
*/
public class SimpleSystemProcessExitCodeMapperTests extends TestCase {
private SimpleSystemProcessExitCodeMapper mapper = new SimpleSystemProcessExitCodeMapper();
/**
* 0 -> ExitStatus.FINISHED
* else -> ExitStatus.FAILED
*/
public void testMapping() {
assertEquals(ExitStatus.FINISHED, mapper.getExitStatus(0));
assertEquals(ExitStatus.FAILED, mapper.getExitStatus(1));
assertEquals(ExitStatus.FAILED, mapper.getExitStatus(-1));
}
}

View File

@@ -0,0 +1,168 @@
package org.springframework.batch.sample.tasklet;
import java.io.File;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.sample.tasklet.SystemCommandException;
import org.springframework.batch.sample.tasklet.SystemCommandTasklet;
import org.springframework.batch.sample.tasklet.SystemProcessExitCodeMapper;
import org.springframework.util.Assert;
/**
* Tests for {@link SystemCommandTasklet}.
*/
public class SystemCommandTaskletIntegrationTests extends TestCase {
private static final Log log = LogFactory.getLog(SystemCommandTaskletIntegrationTests.class);
private SystemCommandTasklet tasklet = new SystemCommandTasklet();
protected void setUp() throws Exception {
tasklet.setEnvironmentParams(null); // inherit from parent process
tasklet.setWorkingDirectory(null); // inherit from parent process
tasklet.setSystemProcessExitCodeMapper(new TestExitCodeMapper());
tasklet.setTimeout(5000); // long enough timeout
}
/**
* Regular usage scenario - successful execution of system command.
*/
public void testExecute() throws Exception {
String command = "java -version";
tasklet.setCommand(command);
tasklet.afterPropertiesSet();
log.info("Executing command: " + command);
ExitStatus exitStatus = tasklet.execute();
assertEquals(ExitStatus.FINISHED, exitStatus);
}
/**
* Failed execution scenario - error exit code returned by system command.
*/
public void testExecuteFailure() throws Exception {
String command = "java -invalid-argument";
tasklet.setCommand(command);
tasklet.afterPropertiesSet();
log.info("Executing command: " + command);
ExitStatus exitStatus = tasklet.execute();
assertEquals(ExitStatus.FAILED, exitStatus);
}
/**
* Failed execution scenario - execution time exceeds timeout.
*/
public void testExecuteTimeout() throws Exception {
String command = "sleep 3";
tasklet.setCommand(command);
tasklet.setTimeout(10);
tasklet.afterPropertiesSet();
log.info("Executing command: " + command);
try {
tasklet.execute();
fail();
}
catch (SystemCommandException e) {
assertTrue(e.getMessage().contains("did not finish successfully within the timeout"));
}
}
/**
* Command property value is required to be set.
*/
public void testCommandNotSet() throws Exception {
tasklet.setCommand(null);
try {
tasklet.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException e) {
// expected
}
tasklet.setCommand("");
try {
tasklet.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException e) {
// expected
}
}
/**
* Timeout must be set to non-zero value.
*/
public void testTimeoutNotSet() throws Exception {
tasklet.setCommand("not-empty placeholder");
tasklet.setTimeout(0);
try {
tasklet.afterPropertiesSet();
fail();
}
catch (IllegalArgumentException e) {
// expected
}
}
/**
* Working directory property must point to an existing location and it must
* be a directory
*/
public void testWorkingDirectory() throws Exception {
File notExistingFile = new File("not-existing-path");
Assert.state(!notExistingFile.exists());
try {
tasklet.setWorkingDirectory(notExistingFile.getCanonicalPath());
fail();
}
catch (IllegalArgumentException e) {
// expected
}
File notDirectory = File.createTempFile(this.getClass().getSimpleName(), null);
Assert.state(notDirectory.exists());
Assert.state(!notDirectory.isDirectory());
try {
tasklet.setWorkingDirectory(notDirectory.getCanonicalPath());
fail();
}
catch (IllegalArgumentException e) {
// expected
}
File directory = notDirectory.getParentFile();
Assert.state(directory.exists());
Assert.state(directory.isDirectory());
// no error expected now
tasklet.setWorkingDirectory(directory.getCanonicalPath());
}
/**
* Exit code mapper containing mapping logic expected by the tests. 0 means
* finished successfully, other value means failure.
*/
private static class TestExitCodeMapper implements SystemProcessExitCodeMapper {
public ExitStatus getExitStatus(int exitCode) {
if (exitCode == 0) {
return ExitStatus.FINISHED;
} else {
return ExitStatus.FAILED;
}
}
}
}