/* * Copyright (c) 2017 Red Hat, Inc. and/or its affiliates. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cheng Fang - Initial API and implementation */ package org.jberet.support.io; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import java.util.Properties; import java.util.concurrent.TimeUnit; import javax.batch.operations.JobOperator; import javax.batch.runtime.BatchStatus; import javax.batch.runtime.StepExecution; import org.apache.commons.exec.ExecuteStreamHandler; import org.jberet.operations.JobOperatorImpl; import org.jberet.runtime.JobExecutionImpl; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Tests for {@link OsCommandBatchlet}. * * @since 1.3.0.Beta5 */ public class OsCommandBatchletTest { public static final String jobName = "org.jberet.support.io.OsCommandBatchletTest"; public static final JobOperator jobOperator = new JobOperatorImpl(); /** * Runs job {@value #jobName}, where {@link OsCommandBatchlet} executes * simple OS commands. * * @throws Exception upon errors */ @Test public void simpleCommands() throws Exception { // run echo command, and should complete successfully with process exit code 0. final Properties jobParams = new Properties(); jobParams.setProperty("commandLine", "echo This is echo from osCommandBatchlet"); runCommand(jobParams, BatchStatus.COMPLETED, String.valueOf(0)); // run echo command, passing the command as comma-separated list, // and setting custom working directory and timeout. // The command should complete successfully with process exit code 0. jobParams.clear(); jobParams.setProperty("commandArray", "echo, abc, xyz, 123"); jobParams.setProperty("workingDir", System.getProperty("java.io.tmpdir")); jobParams.setProperty("timeoutSeconds", String.valueOf(600)); runCommand(jobParams, BatchStatus.COMPLETED, String.valueOf(0)); // run cd command, setting the process exit code for successful completion to 999999. // The job execution should fail, since the process exit code 0 does not match 999999. jobParams.clear(); jobParams.setProperty("commandLine", "cd .."); jobParams.setProperty("commandOkExitValues", String.valueOf(999999)); runCommand(jobParams, BatchStatus.FAILED, String.valueOf(0)); } /** * This test uses a custom stream handler that does nothing. * There should be no output displayed from running the command subprocess. * * @throws Exception upon errors */ @Test public void streamHandler() throws Exception { // run echo command, and should complete successfully with process exit code 0. final Properties jobParams = new Properties(); jobParams.setProperty("commandLine", "echo This is echo from osCommandBatchlet"); jobParams.setProperty("streamHandler", "org.jberet.support.io.OsCommandBatchletTest$NoopStreamHandler"); runCommand(jobParams, BatchStatus.COMPLETED, String.valueOf(0)); } /** * Runs {@code top} command, which continuously displays OS process info. * By setting a timeout, the {@code top} process should be aborted after timeout, * and so the job execution should fail, and the batch exit status is set to * the process exit code (143, interrupted). * * @throws Exception upon errors */ @Test public void timeout() throws Exception { final Properties jobParams = new Properties(); jobParams.setProperty("commandLine", "top"); jobParams.setProperty("timeoutSeconds", String.valueOf(5)); runCommand(jobParams, BatchStatus.FAILED, String.valueOf(143)); } /** * Runs {@code top} command, which continuously displays OS process info. * The job execution is then stopped, which means the {@code top} command * should also be stopped. The batch exit status is set to the process * exit code (143). * * @throws Exception upon errors */ @Test public void stop() throws Exception { final Properties jobParams = new Properties(); jobParams.setProperty("commandLine", "top"); final long jobExecutionId = jobOperator.start(jobName, jobParams); final JobExecutionImpl jobExecution = (JobExecutionImpl) jobOperator.getJobExecution(jobExecutionId); Thread.sleep(3000); jobOperator.stop(jobExecutionId); Thread.sleep(2000); checkJobExecution(jobExecution, BatchStatus.STOPPED, String.valueOf(143)); } protected void runCommand(final Properties jobParams, final BatchStatus expectedBatchStatus, final String expectedExitStatus) throws Exception { final long jobExecutionId = jobOperator.start(jobName, jobParams); final JobExecutionImpl jobExecution = (JobExecutionImpl) jobOperator.getJobExecution(jobExecutionId); jobExecution.awaitTermination(5, TimeUnit.MINUTES); checkJobExecution(jobExecution, expectedBatchStatus, expectedExitStatus); } protected void checkJobExecution(final JobExecutionImpl jobExecution, final BatchStatus expectedBatchStatus, final String expectedExitStatus) { assertEquals(expectedBatchStatus, jobExecution.getBatchStatus()); final List<StepExecution> stepExecutions = jobExecution.getStepExecutions(); assertEquals(1, stepExecutions.size()); final StepExecution stepExecution = stepExecutions.get(0); assertEquals(expectedExitStatus, stepExecution.getExitStatus()); } public static final class NoopStreamHandler implements ExecuteStreamHandler { @Override public void setProcessInputStream(final OutputStream os) throws IOException { } @Override public void setProcessErrorStream(final InputStream is) throws IOException { } @Override public void setProcessOutputStream(final InputStream is) throws IOException { } @Override public void start() throws IOException { } @Override public void stop() throws IOException { } } }