add SystemProcess as wrapper for ProcessBuilder using Strings for simplified input+output
This commit is contained in:
parent
977bd595d8
commit
93774aebe3
@ -0,0 +1,57 @@
|
||||
package net.hostsharing.hsadminng.system;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
public class SystemProcess {
|
||||
private final ProcessBuilder processBuilder;
|
||||
|
||||
@Getter
|
||||
private String stdOut;
|
||||
@Getter
|
||||
private String stdErr;
|
||||
|
||||
public SystemProcess(final String... command) {
|
||||
this.processBuilder = new ProcessBuilder(command);
|
||||
}
|
||||
|
||||
public int execute() throws IOException, InterruptedException {
|
||||
final var process = processBuilder.start();
|
||||
stdOut = fetchOutput(process.getInputStream()); // yeah, twisted ProcessBuilder API
|
||||
stdErr = fetchOutput(process.getErrorStream());
|
||||
return process.waitFor();
|
||||
}
|
||||
|
||||
public int execute(final String input) throws IOException, InterruptedException {
|
||||
final var process = processBuilder.start();
|
||||
feedInput(input, process);
|
||||
stdOut = fetchOutput(process.getInputStream()); // yeah, twisted ProcessBuilder API
|
||||
stdErr = fetchOutput(process.getErrorStream());
|
||||
return process.waitFor();
|
||||
}
|
||||
|
||||
private static void feedInput(final String input, final Process process) throws IOException {
|
||||
try (
|
||||
final OutputStreamWriter stdIn = new OutputStreamWriter(process.getOutputStream()); // yeah, twisted ProcessBuilder API
|
||||
final BufferedWriter writer = new BufferedWriter(stdIn)) {
|
||||
writer.write(input);
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
private static String fetchOutput(final InputStream inputStream) throws IOException {
|
||||
final var output = new StringBuilder();
|
||||
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
for (String line; (line = reader.readLine()) != null; ) {
|
||||
output.append(line).append(System.lineSeparator());
|
||||
}
|
||||
}
|
||||
return output.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package net.hostsharing.hsadminng.system;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
import static org.junit.jupiter.api.condition.OS.LINUX;
|
||||
|
||||
class SystemProcessTest {
|
||||
|
||||
@Test
|
||||
@EnabledOnOs(LINUX)
|
||||
void shouldExecuteAndFetchOutput() throws IOException, InterruptedException {
|
||||
// given
|
||||
final var process = new SystemProcess("bash", "-c", "echo 'Hello, World!'; echo 'Error!' >&2");
|
||||
|
||||
// when
|
||||
final var returnCode = process.execute();
|
||||
|
||||
// then
|
||||
assertThat(returnCode).isEqualTo(0);
|
||||
assertThat(process.getStdOut()).isEqualTo("Hello, World!\n");
|
||||
assertThat(process.getStdErr()).isEqualTo("Error!\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs(LINUX)
|
||||
void shouldReturnErrorCode() throws IOException, InterruptedException {
|
||||
// given
|
||||
final var process = new SystemProcess("false");
|
||||
|
||||
// when
|
||||
final int returnCode = process.execute();
|
||||
|
||||
// then
|
||||
assertThat(returnCode).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs(LINUX)
|
||||
void shouldExecuteAndFeedInput() throws IOException, InterruptedException {
|
||||
// given
|
||||
final var process = new SystemProcess("tr", "[:lower:]", "[:upper:]");
|
||||
|
||||
// when
|
||||
final int returnCode = process.execute("Hallo");
|
||||
|
||||
// then
|
||||
assertThat(returnCode).isEqualTo(0);
|
||||
assertThat(process.getStdOut()).isEqualTo("HALLO\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowExceptionIfProgramNotFound() {
|
||||
// given
|
||||
final var process = new SystemProcess("non-existing program");
|
||||
|
||||
// when
|
||||
final var exception = catchThrowable(process::execute);
|
||||
|
||||
// then
|
||||
assertThat(exception).isInstanceOf(IOException.class)
|
||||
.hasMessage("Cannot run program \"non-existing program\": error=2, No such file or directory");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBeAbleToRunMultipleTimes() throws IOException, InterruptedException {
|
||||
// given
|
||||
final var process = new SystemProcess("true");
|
||||
|
||||
// when
|
||||
process.execute();
|
||||
final int returnCode = process.execute();
|
||||
|
||||
// then
|
||||
assertThat(returnCode).isEqualTo(0);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user