Skip to content

Commit 6f1d103

Browse files
committed
cleanup process utils
1 parent f518c76 commit 6f1d103

File tree

17 files changed

+330
-134
lines changed

17 files changed

+330
-134
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
99
### Changed
1010

1111
* AutomataLib now requires Java 11 at runtime.
12+
* `ProcessUtil#invokeProcess` now handles consumers for stdout and stderr separately.
1213

1314
### Removed
1415

commons/util/src/main/java/net/automatalib/common/util/process/InputStreamConsumer.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.io.BufferedReader;
1919
import java.io.IOException;
2020
import java.io.InputStream;
21+
import java.io.OutputStream;
2122
import java.util.function.Consumer;
2223

2324
import net.automatalib.common.util.IOUtil;
@@ -30,16 +31,19 @@ interface InputStreamConsumer {
3031
void consume(InputStream is) throws IOException;
3132

3233
/**
33-
* Consumes an input stream by throwing away all of its content.
34+
* Consumes an input stream by copying it to a given output stream.
3435
*/
35-
class NOPConsumer implements InputStreamConsumer {
36+
class CopyConsumer implements InputStreamConsumer {
37+
38+
private final OutputStream outputStream;
39+
40+
CopyConsumer(OutputStream outputStream) {
41+
this.outputStream = outputStream;
42+
}
3643

3744
@Override
3845
public void consume(InputStream inputStream) throws IOException {
39-
final byte[] buf = new byte[IOUtil.DEFAULT_BUFFER_SIZE];
40-
while (inputStream.read(buf) >= 0) {
41-
// do nothing
42-
}
46+
inputStream.transferTo(outputStream);
4347
}
4448
}
4549

commons/util/src/main/java/net/automatalib/common/util/process/ProcessUtil.java

Lines changed: 119 additions & 88 deletions
Large diffs are not rendered by default.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/* Copyright (C) 2013-2025 TU Dortmund University
2+
* This file is part of AutomataLib <https://automatalib.net>.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package net.automatalib.common.util.process;
17+
18+
import java.io.IOException;
19+
import java.io.StringReader;
20+
import java.util.Objects;
21+
import java.util.StringJoiner;
22+
23+
import org.testng.Assert;
24+
import org.testng.SkipException;
25+
import org.testng.annotations.BeforeTest;
26+
import org.testng.annotations.Test;
27+
28+
@Test
29+
public class ProcessUtilTest {
30+
31+
private final String process;
32+
33+
public ProcessUtilTest() {
34+
this.process = Objects.requireNonNull(ProcessUtilTest.class.getResource("/process.py")).getPath();
35+
}
36+
37+
@BeforeTest
38+
public void setUp() {
39+
try {
40+
if (ProcessUtil.invokeProcess(new String[] {"python", "--version"}) != 0) {
41+
throw new SkipException("python not supported");
42+
}
43+
} catch (IOException | InterruptedException e) {
44+
throw new SkipException("python not supported");
45+
}
46+
}
47+
48+
@Test
49+
public void testReturnValue() throws IOException, InterruptedException {
50+
Assert.assertEquals(ProcessUtil.invokeProcess(new String[] {process, "abc"}), 0);
51+
Assert.assertEquals(ProcessUtil.invokeProcess(new String[] {process, "abc", "def"}), 1);
52+
53+
Assert.assertEquals(ProcessUtil.invokeProcess(new String[] {process}, new StringReader("abc")), 0);
54+
Assert.assertEquals(ProcessUtil.invokeProcess(new String[] {process}, new StringReader("abc def")), 1);
55+
}
56+
57+
@Test
58+
public void testProcessOutput() throws IOException, InterruptedException {
59+
StringJoiner stdOutJoiner = new StringJoiner("\n");
60+
StringJoiner stdErrBuilder = new StringJoiner("\n");
61+
62+
Assert.assertEquals(ProcessUtil.invokeProcess(new String[] {process, "abc"},
63+
stdOutJoiner::add,
64+
stdErrBuilder::add), 0);
65+
Assert.assertEquals(stdOutJoiner.toString(), "294");
66+
Assert.assertEquals(stdErrBuilder.toString(), "abc");
67+
68+
stdOutJoiner = new StringJoiner("\n");
69+
stdErrBuilder = new StringJoiner("\n");
70+
Assert.assertEquals(ProcessUtil.invokeProcess(new String[] {process, "abc", "def"},
71+
stdOutJoiner::add,
72+
stdErrBuilder::add), 1);
73+
Assert.assertEquals(stdOutJoiner.toString(), "294\n303");
74+
Assert.assertEquals(stdErrBuilder.toString(), "abc\ndef");
75+
76+
stdOutJoiner = new StringJoiner("\n");
77+
stdErrBuilder = new StringJoiner("\n");
78+
Assert.assertEquals(ProcessUtil.invokeProcess(new String[] {process},
79+
new StringReader("abc"),
80+
stdOutJoiner::add,
81+
stdErrBuilder::add), 0);
82+
Assert.assertEquals(stdOutJoiner.toString(), "294");
83+
Assert.assertEquals(stdErrBuilder.toString(), "abc");
84+
85+
stdOutJoiner = new StringJoiner("\n");
86+
stdErrBuilder = new StringJoiner("\n");
87+
Assert.assertEquals(ProcessUtil.invokeProcess(new String[] {process},
88+
new StringReader("abc def"),
89+
stdOutJoiner::add,
90+
stdErrBuilder::add), 1);
91+
Assert.assertEquals(stdOutJoiner.toString(), "294\n303");
92+
Assert.assertEquals(stdErrBuilder.toString(), "abc\ndef");
93+
94+
}
95+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/python
2+
import sys
3+
4+
def main():
5+
argv = len(sys.argv)
6+
7+
if argv > 1: # arg mode
8+
for arg in sys.argv[1:]:
9+
print(sum([ord(c) for c in arg]))
10+
print(arg, file=sys.stderr)
11+
else: # stdin mode
12+
for line in sys.stdin:
13+
for arg in line.split():
14+
argv += 1
15+
print(sum([ord(c) for c in arg]))
16+
print(arg, file=sys.stderr)
17+
18+
sys.exit(argv % 2)
19+
20+
if __name__ == "__main__":
21+
main()

examples/src/main/java/net/automatalib/example/dot/DOTExample.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ private DOTExample() {
4646
// prevent instantiation
4747
}
4848

49-
public static void main(String[] args) throws IOException {
49+
public static void main(String[] args) throws IOException, InterruptedException {
5050
if (DOT.checkUsable()) {
5151
final Random r = new Random(42);
5252
final List<Pair<String, String>> graphs = Arrays.asList(Pair.of("Automaton 1", generateRandomAutomaton(r)),

examples/src/test/java/net/automatalib/example/ExamplesTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public void testDOTExample() throws InvocationTargetException, InterruptedExcept
7878
SwingUtilities.invokeAndWait(() -> {
7979
try {
8080
DOTExample.main(new String[0]);
81-
} catch (IOException e) {
81+
} catch (IOException | InterruptedException e) {
8282
throw new RuntimeException(e);
8383
}
8484
});

modelchecking/ltsmin/src/main/java/net/automatalib/modelchecker/ltsmin/AbstractLTSmin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,8 @@ public Function<String, I> getString2Input() {
284284

285285
private static int runCommandLine(List<String> commandLine) {
286286
try {
287-
LOGGER.debug("Invoking LTSmin binary as: {}", String.join(" ", commandLine));
288-
return ProcessUtil.invokeProcess(commandLine, LOGGER::debug);
287+
LOGGER.debug("Invoking LTSmin binary as: '{}'", String.join(" ", commandLine));
288+
return ProcessUtil.invokeProcess(commandLine, LOGGER::debug, LOGGER::warn);
289289
} catch (IOException | InterruptedException e) {
290290
throw new ModelCheckingException(e);
291291
}

modelchecking/ltsmin/src/main/java/net/automatalib/modelchecker/ltsmin/LTSminUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ public static void detectLTSmin() {
176176
final StringWriter stringWriter = new StringWriter();
177177

178178
try {
179-
final int exitValue = ProcessUtil.invokeProcess(commandLine, stringWriter::append);
179+
final int exitValue = ProcessUtil.invokeProcess(commandLine, stringWriter::append, LOGGER::warn);
180180

181181
if (exitValue == VERSION_EXIT) {
182182
return LTSminVersion.parse(stringWriter.toString());

0 commit comments

Comments
 (0)