Skip to content
Snippets Groups Projects
Commit 2b07e9e3 authored by Lars Erik Blümke's avatar Lars Erik Blümke
Browse files

migration and tests of TeeFilter

parent 94fcfea0
No related branches found
No related tags found
No related merge requests found
package kieker.analysis.plugin.filter.forward;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import teetime.stage.basic.AbstractFilter;
/**
* This filter has exactly one input port and one output port.
*
* A simple message is printed to a configurable stream and all objects are forwarded to the output port.
*
* @author Matthias Rohr, Jan Waller, Lars Erik Bluemke
*
* @since 1.2
*/
public class TeeFilter extends AbstractFilter<Object> {
/** The default value of the encoding property which determines that the filter uses utf-8. */
public static final String DEFAULT_ENCODING = "UTF-8";
/** The default value of the stream property which determines that the filter appends or overwrites a file. */
public static final boolean DEFAULT_STREAM_APPEND = true;
private final PrintStream printStream;
private final String printStreamName;
private final boolean active;
private final boolean append;
private final String encoding;
/**
* Predefined types of streams for the {@link TeeFilter}.<br>
* <b>STDLOG</b> = standard log<br>
* <b>STDOUT</b> = standard output<br>
* <b>STDERR</b> = standard error output<br>
* <b>NULL</b> = filter doesn't print anything
*/
public enum TeeFilterStreamType {
STDLOG, STDOUT, STDERR, NULL
}
/**
* Creates a new instance of this class using the given parameters. Uses one of the predefined {@link TeeFilterStreamType}s.
*
* @param streamType
* Determines which of the predefined {@link TeeFilterStreamType}s the filter uses.
* @param encoding
* Determines which encoding the filter uses. Pass null for default encoding {@value #DEFAULT_ENCODING}.
*/
public TeeFilter(final TeeFilterStreamType streamType, final String encoding) {
// Get the encoding.
if (encoding != null) {
this.encoding = encoding;
} else {
this.encoding = DEFAULT_ENCODING;
}
this.printStreamName = null; // NOPMD (null)
this.append = false;
// Decide which stream to be used
if (streamType.equals(TeeFilterStreamType.STDLOG)) {
this.printStream = null; // NOPMD (null)
this.active = true;
} else if (streamType.equals(TeeFilterStreamType.STDOUT)) {
this.printStream = System.out;
this.active = true;
} else if (streamType.equals(TeeFilterStreamType.STDERR)) {
this.printStream = System.err;
this.active = true;
} else {
this.printStream = null; // NOPMD (null)
this.active = false;
}
}
/**
* Creates a new instance of this class using the given parameters. Uses a {@link FileOutputStream}.
*
* @param fileName
* The system dependent file name for the {@link FileOutputStream}.
* @param encoding
* Determines which encoding the filter uses. Pass null for default encoding {@value #DEFAULT_ENCODING}.
* @param append
* Determines whether the filter appends or overwrites a file.
*/
public TeeFilter(final String fileName, final String encoding, final boolean append) {
// Get the encoding.
if (encoding != null) {
this.encoding = encoding;
} else {
this.encoding = DEFAULT_ENCODING;
}
this.append = append;
PrintStream tmpPrintStream;
try {
tmpPrintStream = new PrintStream(new FileOutputStream(fileName, this.append), false, this.encoding);
} catch (final UnsupportedEncodingException ex) {
this.logger.error("Failed to initialize " + fileName, ex);
tmpPrintStream = null; // NOPMD (null)
} catch (final FileNotFoundException ex) {
this.logger.error("Failed to initialize " + fileName, ex);
tmpPrintStream = null; // NOPMD (null)
}
this.printStream = tmpPrintStream;
this.printStreamName = fileName;
this.active = true;
}
@Override
public void onTerminating() throws Exception {
if ((this.printStream != null) && (this.printStream != System.out) && (this.printStream != System.err)) {
this.printStream.close();
}
super.onTerminating();
}
/**
* This method receives incoming objects from the filter's input port. Every object will be printed into a stream (based on the configuration) before the
* filter sends it to the output port.
*
* @param object
* The new object.
*/
@Override
protected void execute(final Object object) {
if (this.active) {
final StringBuilder sb = new StringBuilder(128);
sb.append(this.getId());
sb.append('(').append(object.getClass().getSimpleName()).append(") ").append(object.toString());
final String record = sb.toString();
if (this.printStream != null) {
this.printStream.println(record);
} else {
this.logger.info(record);
}
}
this.outputPort.send(object);
}
public String getPrintStreamName() {
return printStreamName;
}
}
package kieker.analysis.plugin.filter.forward;
import static teetime.framework.test.StageTester.test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import org.junit.Assert;
import org.junit.Test;
import kieker.analysis.exception.AnalysisConfigurationException;
/**
* This test makes sure that the {@link TeeFilter} writes (with regard to the append property) correctly into files.
*
* @author Nils Christian Ehmke, Lars Erik Bluemke
*
* @since 1.10
*/
public class TeeFilterTest {
public TeeFilterTest() {
// empty default constructor
}
@Test
public void testFileAppend() throws IOException {
final File tempFile = File.createTempFile("kieker", ".tmp");
this.executeAnalysis(tempFile, false, Arrays.asList(1, 2, 3));
this.executeAnalysis(tempFile, true, Arrays.asList(4, 5, 6));
final List<Integer> contentOfFile = this.readFromFile(tempFile);
Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6), contentOfFile);
}
@Test
public void testFileOverwrite() throws IOException, IllegalStateException, AnalysisConfigurationException {
final File tempFile = File.createTempFile("kieker", ".tmp");
this.executeAnalysis(tempFile, false, Arrays.asList(1, 2, 3));
this.executeAnalysis(tempFile, false, Arrays.asList(4, 5, 6));
final List<Integer> contentOfFile = this.readFromFile(tempFile);
Assert.assertEquals(Arrays.asList(4, 5, 6), contentOfFile);
}
private void executeAnalysis(final File tempFile, final boolean append, final List<Integer> objectsToWrite) {
final TeeFilter teeFilter = new TeeFilter(tempFile.getAbsolutePath(), null, append);
test(teeFilter).and().send(objectsToWrite).to(teeFilter.getInputPort()).start();
}
private List<Integer> readFromFile(final File tempFile) throws FileNotFoundException {
final List<Integer> result = new ArrayList<Integer>();
Scanner scanner = null;
try {
scanner = new Scanner(tempFile, TeeFilter.DEFAULT_ENCODING);
// The tee filter writes something like "TeeFilter-3(Integer) 4" - therefore we have to parse this String a little bit.
while (scanner.hasNextLine()) {
final String line = scanner.nextLine();
result.add(Integer.parseInt(line.split(" ")[1]));
}
} finally {
if (scanner != null) {
scanner.close();
}
}
return result;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment