package org.gridkit.jvmtool.codec.stacktrace;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.gridkit.jvmtool.codec.stacktrace.EventSeqEqualToCondition.exactlyAs;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.gridkit.jvmtool.event.ErrorEvent;
import org.gridkit.jvmtool.event.Event;
import org.gridkit.jvmtool.event.EventReader;
import org.gridkit.jvmtool.event.UniversalEventWriter;
import org.gridkit.jvmtool.stacktrace.CounterCollection;
import org.gridkit.jvmtool.stacktrace.StackFrame;
import org.gridkit.jvmtool.stacktrace.StackFrameList;
import org.gridkit.jvmtool.stacktrace.StackTraceReader;
import org.gridkit.jvmtool.stacktrace.ThreadEventCodec;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
public class ThreadEventReaderTest {
@Rule
public TestName testName = new TestName();
@Test
public void read_dump_v1() throws FileNotFoundException, IOException {
EventReader<Event> reader = ThreadEventCodec.createEventReader(new FileInputStream("src/test/resources/dump_v1.std"));
int n = 0;
for(Event e: reader) {
if (e instanceof ErrorEvent) {
fail("Error", ((ErrorEvent) e).exception());
}
++n;
}
System.out.println("Read " + n + " traces from file");
}
@Test
public void read_dump_v2() throws FileNotFoundException, IOException {
EventReader<Event> reader = ThreadEventCodec.createEventReader(new FileInputStream("src/test/resources/dump_v2.std"));
int n = 0;
for(Event e: reader) {
if (e instanceof ErrorEvent) {
fail("Error", ((ErrorEvent) e).exception());
}
// System.out.println(((MultiCounterEvent)e).counters());
++n;
}
System.out.println("Read " + n + " traces from file");
}
@Test
public void read_dump_v1_rewrite_and_compare() throws FileNotFoundException, IOException {
String sourceFile = "src/test/resources/dump_v1.std";
File file = new File("target/tmp/" + testName.getMethodName() + "-" + System.currentTimeMillis() + ".std");
file.getParentFile().mkdirs();
file.delete();
FileOutputStream fow = new FileOutputStream(file);
UniversalEventWriter writer = ThreadEventCodec.createEventWriter(fow);
EventReader<Event> reader = ThreadEventCodec.createEventReader(new FileInputStream(sourceFile));
copyAllTraces(reader, writer);
writer.close();
System.out.println("New file " + file.length() + " bytes (original " + new File(sourceFile).length() + " bytes)");
reader = ThreadEventCodec.createEventReader(new FileInputStream(file));
EventReader<Event> origReader = ThreadEventCodec.createEventReader(new FileInputStream("src/test/resources/dump_v1.std"));
assertThat((Iterable<Event>)reader).is(exactlyAs(origReader));
}
@Test
public void read_dump_v2_rewrite_and_compare() throws FileNotFoundException, IOException {
File sourceFile = new File("src/test/resources/dump_v2.std");
File file = new File("target/tmp/" + testName.getMethodName() + "-" + System.currentTimeMillis() + ".std");
file.getParentFile().mkdirs();
file.delete();
FileOutputStream fow = new FileOutputStream(file);
UniversalEventWriter writer = ThreadEventCodec.createEventWriter(fow);
EventReader<Event> reader = ThreadEventCodec.createEventReader(new FileInputStream(sourceFile));
copyAllTraces(reader, writer);
writer.close();
System.out.println("New file " + file.length() + " bytes (original " + sourceFile.length() + " bytes)");
reader = ThreadEventCodec.createEventReader(new FileInputStream(file));
EventReader<Event> origReader = ThreadEventCodec.createEventReader(new FileInputStream(sourceFile));
assertThat((Iterable<Event>)reader).is(exactlyAs(origReader));
}
@Test
public void read_dump_v4_rewrite_and_compare() throws FileNotFoundException, IOException {
File sourceFile = new File("src/test/resources/dump_v4.std");
File file = new File("target/tmp/" + testName.getMethodName() + "-" + System.currentTimeMillis() + ".std");
file.getParentFile().mkdirs();
file.delete();
FileOutputStream fow = new FileOutputStream(file);
UniversalEventWriter writer = ThreadEventCodec.createEventWriter(fow);
EventReader<Event> reader = ThreadEventCodec.createEventReader(new FileInputStream(sourceFile));
copyAllTraces(reader, writer);
writer.close();
System.out.println("New file " + file.length() + " bytes (original " + sourceFile.length() + " bytes)");
reader = ThreadEventCodec.createEventReader(new FileInputStream(file));
EventReader<Event> origReader = ThreadEventCodec.createEventReader(new FileInputStream(sourceFile));
assertThat((Iterable<Event>)reader).is(exactlyAs(origReader));
}
void assertEqual(StackTraceReader r1, StackTraceReader r2) throws IOException {
if (!r1.isLoaded()) {
r1.loadNext();
}
if (!r2.isLoaded()) {
r2.loadNext();
}
int n = 0;
while(r1.isLoaded() && r2.isLoaded()) {
assertSameState(r1, r2);
r1.loadNext();
r2.loadNext();
++n;
}
if (r1.isLoaded()) {
Assert.fail("Loaded " + n + " traces, expected more");
}
if (r2.isLoaded()) {
Assert.fail("Loaded excepted " + n + " traces, but more is available");
}
}
private void assertSameState(StackTraceReader r1, StackTraceReader r2) {
Assert.assertEquals("ThreadID", r1.getThreadId(), r2.getThreadId());
Assert.assertEquals("ThreadName", r1.getThreadName(), r2.getThreadName());
Assert.assertEquals("Timestamp", r1.getTimestamp(), r2.getTimestamp());
Assert.assertEquals("State", r1.getThreadState(), r2.getThreadState());
CounterCollection c1 = r1.getCounters();
CounterCollection c2 = r2.getCounters();
for(String key: c1) {
Assert.assertEquals("Counter #" + key, c1.getValue(key), c2.getValue(key));
}
for(String key: c2) {
Assert.assertEquals("Counter #" + key, c1.getValue(key), c2.getValue(key));
}
assertEqualTraces(r1.getStackTrace(), r2.getStackTrace());
}
private void copyAllTraces(EventReader<Event> reader, UniversalEventWriter writer) throws IOException {
int tn = 0;
int ntn = 0;
for(Event e: reader) {
if (e instanceof ThreadSnapshotEvent) {
++tn;
}
else {
++ntn;
}
writer.store(e);
}
System.out.println("Copy " + (tn + ntn) + " traces (" + tn + " + " + ntn + ")");
}
void assertEqualTraces(StackFrameList s1, StackFrameList s2) {
StringBuilder sb1 = new StringBuilder();
for(StackFrame f: s1) {
sb1.append(f.toString());
sb1.append('\n');
}
StringBuilder sb2 = new StringBuilder();
for(StackFrame f: s2) {
sb2.append(f.toString());
sb2.append('\n');
}
Assert.assertEquals("Stack trace", sb1.toString(), sb2.toString());
}
}