Commit 32499faf authored by Nils Christian Ehmke's avatar Nils Christian Ehmke

Tests for the monitoring import and minor bug fixes

parent 8792e211
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
......@@ -24,6 +25,16 @@
<groupId>org.jfxtras</groupId>
<artifactId>jfxtras-controls</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -293,7 +293,7 @@ final class MonitoringLogImporter {
// Make sure that the timestamp is always in milliseconds
if ( DESTINATION_TIMESTAMP_TIME_UNIT != ivSourceTimeUnit ) {
final long newTimestamp = DESTINATION_TIMESTAMP_TIME_UNIT.convert( timestamp, ivSourceTimeUnit );
final long newTimestamp = DESTINATION_TIMESTAMP_TIME_UNIT.convert( lastMethodCall.getTimestamp( ), ivSourceTimeUnit );
lastMethodCall.setTimestamp( newTimestamp );
}
......@@ -354,18 +354,18 @@ final class MonitoringLogImporter {
try {
final Class<?> recordClass = Class.forName( recordName );
final Field sizeField = recordClass.getDeclaredField( "SIZE" );
size = (byte) sizeField.get( null );
size = (byte) (int) sizeField.get( null );
ivIgnoredRecordsSizeMap.put( aRecordKey, size );
ivIgnoredRecords++;
} catch ( final Exception ex ) {
// We have no chance. We cannot skip the record, as we don't know its size.
throw new RuntimeException( String.format( ivResourceBundle.getString( "errorMessageUnknownRecord" ), recordName ) );
throw new RuntimeException( String.format( ivResourceBundle.getString( "errorMessageUnknownRecord" ), recordName ), ex );
}
} else {
size = ivIgnoredRecordsSizeMap.get( aRecordKey );
}
ivIgnoredRecords++;
skipBytes( size, aByteBuffer );
}
......@@ -496,33 +496,44 @@ final class MonitoringLogImporter {
@Override
public boolean equals( final Object obj ) {
if ( this == obj )
if ( this == obj ) {
return true;
if ( obj == null )
}
if ( obj == null ) {
return false;
if ( getClass( ) != obj.getClass( ) )
}
if ( getClass( ) != obj.getClass( ) ) {
return false;
}
final AggregationKey other = (AggregationKey) obj;
if ( ivClass == null ) {
if ( other.ivClass != null )
if ( other.ivClass != null ) {
return false;
} else if ( !ivClass.equals( other.ivClass ) )
}
} else if ( !ivClass.equals( other.ivClass ) ) {
return false;
}
if ( ivException == null ) {
if ( other.ivException != null )
if ( other.ivException != null ) {
return false;
} else if ( !ivException.equals( other.ivException ) )
}
} else if ( !ivException.equals( other.ivException ) ) {
return false;
}
if ( ivHost == null ) {
if ( other.ivHost != null )
if ( other.ivHost != null ) {
return false;
} else if ( !ivHost.equals( other.ivHost ) )
}
} else if ( !ivHost.equals( other.ivHost ) ) {
return false;
}
if ( ivMethod == null ) {
if ( other.ivMethod != null )
if ( other.ivMethod != null ) {
return false;
} else if ( !ivMethod.equals( other.ivMethod ) )
}
} else if ( !ivMethod.equals( other.ivMethod ) ) {
return false;
}
return true;
}
......
package kieker.diagnosis.service.data;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.hamcrest.collection.IsEmptyCollection.empty;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.number.OrderingComparison.greaterThan;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import com.carrotsearch.hppc.ByteArrayList;
import com.google.common.io.Files;
import com.google.inject.Guice;
import com.google.inject.Injector;
import kieker.common.record.AbstractMonitoringRecord;
import kieker.common.record.flow.trace.TraceMetadata;
import kieker.common.record.flow.trace.operation.AfterOperationEvent;
import kieker.common.record.flow.trace.operation.AfterOperationFailedEvent;
import kieker.common.record.flow.trace.operation.BeforeOperationEvent;
import kieker.common.record.misc.KiekerMetadataRecord;
import kieker.common.record.system.CPUUtilizationRecord;
import kieker.common.util.registry.IRegistry;
import kieker.common.util.registry.Registry;
import kieker.diagnosis.KiekerTraceDiagnosisModule;
public class MonitoringLogServiceTest {
@Rule
public TemporaryFolder ivTemporaryFolder = new TemporaryFolder( );
@Rule
public ExpectedException ivExpectedException = ExpectedException.none( );
private ByteArrayList ivByteList;
private IRegistry<String> ivStringRegistry;
private MonitoringLogService ivService;
@Before
public void setUp( ) {
ivByteList = new ByteArrayList( );
ivStringRegistry = new Registry<>( );
final Injector injector = Guice.createInjector( new KiekerTraceDiagnosisModule( ) );
ivService = injector.getInstance( MonitoringLogService.class );
}
@Test
public void testEmptyDirectory( ) {
// Import the directory
final File directory = ivTemporaryFolder.getRoot( );
ivService.importMonitoringLog( directory );
// Make sure that nothing has been imported
assertThat( ivService.getMethods( ), is( empty( ) ) );
assertThat( ivService.getAggreatedMethods( ), is( empty( ) ) );
assertThat( ivService.getTraceRoots( ), is( empty( ) ) );
assertThat( ivService.getProcessedBytes( ), is( 0L ) );
}
@Test
public void testSingleTrace( ) throws Exception {
// Prepare the data
writeRecord( new TraceMetadata( 1L, 0L, "0", "host", 0L, 0 ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeMappingFile( );
finishWriting( );
// Import the directory
final File directory = ivTemporaryFolder.getRoot( );
ivService.importMonitoringLog( directory );
// Make sure that the import worked as intended
assertThat( ivService.getMethods( ), hasSize( 2 ) );
assertThat( ivService.getAggreatedMethods( ), hasSize( 2 ) );
assertThat( ivService.getTraceRoots( ), hasSize( 1 ) );
assertThat( ivService.getProcessedBytes( ), is( greaterThan( 0L ) ) );
}
@Test
public void testTwoInterleavedTrace( ) throws Exception {
// Prepare the data
writeRecord( new TraceMetadata( 1L, 0L, "0", "host", 0L, 0 ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1" ) );
writeRecord( new TraceMetadata( 2L, 0L, "0", "host", 0L, 0 ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 2L, 0, "op1", "class2" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1" ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 2L, 0, "op2", "class2" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 2L, 0, "op2", "class2" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 2L, 0, "op1", "class2" ) );
writeMappingFile( );
finishWriting( );
// Import the directory
final File directory = ivTemporaryFolder.getRoot( );
ivService.importMonitoringLog( directory );
// Make sure that the import worked as intended
assertThat( ivService.getMethods( ), hasSize( 4 ) );
assertThat( ivService.getAggreatedMethods( ), hasSize( 4 ) );
assertThat( ivService.getTraceRoots( ), hasSize( 2 ) );
assertThat( ivService.getProcessedBytes( ), is( greaterThan( 0L ) ) );
}
@Test
public void testFailedTrace( ) throws Exception {
// Prepare the data
writeRecord( new TraceMetadata( 1L, 0L, "0", "host", 0L, 0 ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1" ) );
writeRecord( new AfterOperationFailedEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1", "cause" ) );
writeRecord( new AfterOperationFailedEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1", "cause" ) );
writeMappingFile( );
finishWriting( );
// Import the directory
final File directory = ivTemporaryFolder.getRoot( );
ivService.importMonitoringLog( directory );
// Make sure that the import worked as intended
assertThat( ivService.getMethods( ), hasSize( 2 ) );
assertThat( ivService.getAggreatedMethods( ), hasSize( 2 ) );
assertThat( ivService.getTraceRoots( ), hasSize( 1 ) );
assertThat( ivService.getProcessedBytes( ), is( greaterThan( 0L ) ) );
}
@Test
public void testMethodAggregation( ) throws Exception {
// Prepare the data
writeRecord( new TraceMetadata( 1L, 0L, "0", "host", 0L, 0 ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1" ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class2" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class2" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeMappingFile( );
finishWriting( );
// Import the directory
final File directory = ivTemporaryFolder.getRoot( );
ivService.importMonitoringLog( directory );
// Make sure that the import worked as intended
assertThat( ivService.getMethods( ), hasSize( 4 ) );
assertThat( ivService.getAggreatedMethods( ), hasSize( 3 ) );
assertThat( ivService.getTraceRoots( ), hasSize( 1 ) );
assertThat( ivService.getProcessedBytes( ), is( greaterThan( 0L ) ) );
}
@Test
public void testIncompleteTrace( ) throws Exception {
// Prepare the data
writeRecord( new TraceMetadata( 1L, 0L, "0", "host", 0L, 0 ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1" ) );
writeMappingFile( );
finishWriting( );
// Import the directory
final File directory = ivTemporaryFolder.getRoot( );
ivService.importMonitoringLog( directory );
// Make sure that the import worked as intended
assertThat( ivService.getMethods( ), hasSize( 0 ) );
assertThat( ivService.getAggreatedMethods( ), hasSize( 0 ) );
assertThat( ivService.getTraceRoots( ), hasSize( 0 ) );
assertThat( ivService.getIncompleteTraces( ), is( 1 ) );
assertThat( ivService.getProcessedBytes( ), is( greaterThan( 0L ) ) );
}
@Test
public void testDanglingRecords( ) throws Exception {
// Prepare the data
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeRecord( new BeforeOperationEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 1L, 0, "op2", "class1" ) );
writeRecord( new AfterOperationEvent( System.currentTimeMillis( ), 1L, 0, "op1", "class1" ) );
writeMappingFile( );
finishWriting( );
// Import the directory
final File directory = ivTemporaryFolder.getRoot( );
ivService.importMonitoringLog( directory );
// Make sure that the import worked as intended
assertThat( ivService.getMethods( ), hasSize( 0 ) );
assertThat( ivService.getAggreatedMethods( ), hasSize( 0 ) );
assertThat( ivService.getTraceRoots( ), hasSize( 0 ) );
assertThat( ivService.getDanglingRecords( ), is( 4 ) );
assertThat( ivService.getProcessedBytes( ), is( greaterThan( 0L ) ) );
}
@Test
public void testDurationConversion( ) throws Exception {
// Prepare the data
writeRecord( new TraceMetadata( 1L, 0L, "0", "host", 0L, 0 ) );
writeRecord( new KiekerMetadataRecord( "0", "0", "0", 0, false, 0L, TimeUnit.SECONDS.name( ), 0 ) );
writeRecord( new BeforeOperationEvent( 10, 1L, 0, "op1", "class1" ) );
writeRecord( new AfterOperationFailedEvent( 20, 1L, 0, "op1", "class1", "cause" ) );
writeMappingFile( );
finishWriting( );
// Import the directory
final File directory = ivTemporaryFolder.getRoot( );
ivService.importMonitoringLog( directory );
// Make sure that the import worked as intended
final MethodCall methodCall = ivService.getMethods( ).get( 0 );
assertThat( methodCall.getDuration( ), is( 10000000000L ) );
}
@Test
public void testTimestampConversion( ) throws Exception {
// Prepare the data
writeRecord( new TraceMetadata( 1L, 0L, "0", "host", 0L, 0 ) );
writeRecord( new KiekerMetadataRecord( "0", "0", "0", 0, false, 0L, TimeUnit.SECONDS.name( ), 0 ) );
writeRecord( new BeforeOperationEvent( 10, 1L, 0, "op1", "class1" ) );
writeRecord( new AfterOperationFailedEvent( 20, 1L, 0, "op1", "class1", "cause" ) );
writeMappingFile( );
finishWriting( );
// Import the directory
final File directory = ivTemporaryFolder.getRoot( );
ivService.importMonitoringLog( directory );
// Make sure that the import worked as intended
final MethodCall methodCall = ivService.getMethods( ).get( 0 );
assertThat( methodCall.getTimestamp( ), is( 10000L ) );
}
@Test
public void testIgnoreRecord( ) throws Exception {
// Prepare the data
writeRecord( new CPUUtilizationRecord( 0L, "", "", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) );
writeRecord( new CPUUtilizationRecord( 1L, "", "", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) );
writeMappingFile( );
finishWriting( );
// Import the directory
final File directory = ivTemporaryFolder.getRoot( );
ivService.importMonitoringLog( directory );
// Make sure that the import worked as intended
assertThat( ivService.getMethods( ), hasSize( 0 ) );
assertThat( ivService.getIgnoredRecords( ), is( 2 ) );
}
@Test
public void testUnknownRecord( ) throws Exception {
// Prepare the data
writeRecord( new UnknownRecord( ) );
writeMappingFile( );
finishWriting( );
// The import should not work
ivExpectedException.expect( RuntimeException.class );
// Import the directory
final File directory = ivTemporaryFolder.getRoot( );
ivService.importMonitoringLog( directory );
}
private void writeRecord( final AbstractMonitoringRecord aRecord ) {
// Register the record name
final int recordKey = ivStringRegistry.get( aRecord.getClass( ).getName( ) );
// Register the record's strings
aRecord.registerStrings( ivStringRegistry );
// Now write the record into our buffer
final byte[] byteArray = new byte[aRecord.getSize( ) + 4 + 8];
final ByteBuffer byteBuffer = ByteBuffer.wrap( byteArray );
byteBuffer.putInt( recordKey );
byteBuffer.putLong( System.currentTimeMillis( ) );
aRecord.writeBytes( byteBuffer, ivStringRegistry );
byteBuffer.flip( );
ivByteList.add( byteArray );
}
private void writeMappingFile( ) throws IOException {
// Collect the mappings
final StringBuilder stringBuilder = new StringBuilder( );
final Object[] allStrings = ivStringRegistry.getAll( );
for ( final Object string : allStrings ) {
final int id = ivStringRegistry.get( (String) string );
stringBuilder.append( "$" ).append( id ).append( "=" ).append( string ).append( "\n" );
}
// Write the mapping file
final File mappingFile = new File( ivTemporaryFolder.getRoot( ), "kieker.map" );
Files.write( stringBuilder.toString( ), mappingFile, Charset.forName( "UTF-8" ) );
}
private void finishWriting( ) throws IOException {
final File binaryFile = new File( ivTemporaryFolder.getRoot( ), "kieker.bin" );
ivByteList.trimToSize( );
Files.write( ivByteList.buffer, binaryFile );
}
private static class UnknownRecord extends AbstractMonitoringRecord {
private static final long serialVersionUID = 1L;
@Override
public Object[] toArray( ) {
return null;
}
@Override
public void writeBytes( final ByteBuffer aBuffer, final IRegistry<String> aStringRegistry ) throws BufferOverflowException {
}
@Override
public void initFromBytes( final ByteBuffer aBuffer, final IRegistry<String> aStringRegistry ) throws BufferUnderflowException {
}
@Override
public void initFromArray( final Object[] aValues ) {
}
@Override
public Class<?>[] getValueTypes( ) {
return null;
}
@Override
public int getSize( ) {
return 0;
}
}
}
......@@ -33,9 +33,9 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
......
......@@ -66,7 +66,7 @@
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
</dependency>
<dependency>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment