package org.gridkit.jvmtool.stacktrace; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; public class StackTraceReaderTest { @Rule public TestName testName = new TestName(); @Test public void read_dump_v1() throws FileNotFoundException, IOException { StackTraceReader reader = StackTraceCodec.newReader(new FileInputStream("src/test/resources/dump_v1.std")); if (!reader.isLoaded()) { reader.loadNext(); } int n = 0; while(reader.isLoaded()) { reader.loadNext(); ++n; } System.out.println("Read " + n + " traces from file"); } @Test public void read_dump_v2() throws FileNotFoundException, IOException { StackTraceReader reader = StackTraceCodec.newReader(new FileInputStream("src/test/resources/dump_v2.std")); if (!reader.isLoaded()) { reader.loadNext(); } int n = 0; while(reader.isLoaded()) { // System.out.println(reader.getCounters() + " - " + reader.getThreadName()); reader.loadNext(); ++n; } System.out.println("Read " + n + " traces from file"); } @Test public void read_dump_v1_rewrite_and_compare() throws FileNotFoundException, IOException { File file = new File("target/tmp/" + testName.getMethodName() + "-" + System.currentTimeMillis() + ".std"); file.getParentFile().mkdirs(); file.delete(); FileOutputStream fow = new FileOutputStream(file); StackTraceWriter writer = StackTraceCodec.newWriter(fow); StackTraceReader reader = StackTraceCodec.newReader(new FileInputStream("src/test/resources/dump_v1.std")); copyAllTraces(reader, writer); writer.close(); reader = StackTraceCodec.newReader(new FileInputStream(file)); StackTraceReader origReader = StackTraceCodec.newReader(new FileInputStream("src/test/resources/dump_v1.std")); assertEqual(origReader, reader); } @Test public void read_dump_v2_rewrite_and_compare() throws FileNotFoundException, IOException { File file = new File("target/tmp/" + testName.getMethodName() + "-" + System.currentTimeMillis() + ".std"); file.getParentFile().mkdirs(); file.delete(); FileOutputStream fow = new FileOutputStream(file); StackTraceWriter writer = StackTraceCodec.newWriter(fow); StackTraceReader reader = StackTraceCodec.newReader(new FileInputStream("src/test/resources/dump_v2.std")); copyAllTraces(reader, writer); writer.close(); reader = StackTraceCodec.newReader(new FileInputStream(file)); StackTraceReader origReader = StackTraceCodec.newReader(new FileInputStream("src/test/resources/dump_v2.std")); assertEqual(origReader, reader); } 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(StackTraceReader reader, StackTraceWriter writer) throws IOException { if (!reader.isLoaded()) { reader.loadNext(); } while(reader.isLoaded()) { copyTrace(reader, writer); reader.loadNext(); } } private void copyTrace(StackTraceReader reader, StackTraceWriter writer) throws IOException { ThreadCapture snap = new ThreadCapture(); snap.threadId = reader.getThreadId(); snap.threadName = reader.getThreadName(); snap.state = reader.getThreadState(); snap.timestamp = reader.getTimestamp(); snap.counters.copyFrom(reader.getCounters()); snap.elements = reader.getTrace(); writer.write(snap); } private 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()); } }