Tests - cleanup of stack traces in test log file

This commit is contained in:
dragonmacher 2020-09-24 18:19:28 -04:00
parent b7c8056c8a
commit e5358323d8
24 changed files with 889 additions and 678 deletions

View file

@ -0,0 +1,81 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package generic.concurrent.io;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import ghidra.util.Msg;
import utilities.util.reflection.ReflectionUtilities;
import utility.function.Dummy;
/**
* Class to pass to a thread pool that will consume all output from an external process. This is
* a {@link Runnable} that get submitted to a thread pool. This class records the data it reads
*/
public class IOResult implements Runnable {
public static final String THREAD_POOL_NAME = "I/O Thread Pool";
private List<String> outputLines = new ArrayList<String>();
private BufferedReader commandOutput;
private final Throwable inception;
private Consumer<String> consumer = Dummy.consumer();
public IOResult(InputStream input) {
this(ReflectionUtilities.createThrowableWithStackOlderThan(IOResult.class), input);
}
public IOResult(Throwable inception, InputStream input) {
this.inception = inception;
commandOutput = new BufferedReader(new InputStreamReader(input));
}
public void setConsumer(Consumer<String> consumer) {
this.consumer = consumer;
}
public String getOutputAsString() {
StringBuilder buffy = new StringBuilder();
for (String line : outputLines) {
buffy.append(line);
}
return buffy.toString();
}
public List<String> getOutput() {
return outputLines;
}
@Override
public void run() {
String line = null;
try {
while ((line = commandOutput.readLine()) != null) {
consumer.accept(line);
outputLines.add(line);
}
}
catch (Exception e) {
String inceptionString = ReflectionUtilities.stackTraceToString(inception);
Msg.debug(IOResult.class,
"Exception reading output from process. Created from:\n" + inceptionString, e);
}
}
}

View file

@ -0,0 +1,70 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package generic.concurrent.io;
import java.io.InputStream;
import java.util.concurrent.Future;
import java.util.function.Consumer;
import generic.concurrent.GThreadPool;
import utilities.util.reflection.ReflectionUtilities;
import utility.function.Dummy;
/**
* A class that allows clients to <b>asynchronously</b> consume the output of a {@link Process}s
* input and error streams. The task is asynchronous to avoid deadlocks when both streams need
* to be read in order for the process to proceed.
*/
public class ProcessConsumer {
/**
* Read the given input stream line-by-line.
*
* <p>To get all output after all reading is done you can call the blocking operation
* {@link Future#get()}.
*
* @param is the input stream
* @return the future that will be complete when all lines are read
*/
public static Future<IOResult> consume(InputStream is) {
return consume(is, Dummy.consumer());
}
/**
* Read the given input stream line-by-line.
*
* <p>If you wish to get all output after all reading is done you can call the blocking
* operation {@link Future#get()}.
*
* @param is the input stream
* @param lineConsumer the line consumer; may be null
* @return the future that will be complete when all lines are read
*/
public static Future<IOResult> consume(InputStream is,
Consumer<String> lineConsumer) {
lineConsumer = Dummy.ifNull(lineConsumer);
Throwable inception = ReflectionUtilities.filterJavaThrowable(
ReflectionUtilities.createThrowableWithStackOlderThan(ProcessConsumer.class));
GThreadPool pool = GThreadPool.getSharedThreadPool(IOResult.THREAD_POOL_NAME);
IOResult runnable = new IOResult(inception, is);
runnable.setConsumer(lineConsumer);
Future<IOResult> future = pool.submit(runnable, runnable);
return future;
}
}