diff --git a/src/main/java/com/tagtraum/perf/gcviewer/ctrl/impl/GCViewerGuiBuilder.java b/src/main/java/com/tagtraum/perf/gcviewer/ctrl/impl/GCViewerGuiBuilder.java index 243e16e1..46f7f9ec 100644 --- a/src/main/java/com/tagtraum/perf/gcviewer/ctrl/impl/GCViewerGuiBuilder.java +++ b/src/main/java/com/tagtraum/perf/gcviewer/ctrl/impl/GCViewerGuiBuilder.java @@ -232,7 +232,7 @@ private GCViewerGuiMenuBar initMenuBar(Map actions, StayOpenCheckBoxMenuItem menuItemConcurrentGcBeginEnd = new StayOpenCheckBoxMenuItem(LocalisationHelper.getString("main_frame_menuitem_concurrent_collection_begin_end"), true); menuItemConcurrentGcBeginEnd.setMnemonic(LocalisationHelper.getString("main_frame_menuitem_mnemonic_concurrent_collection_begin_end").charAt(0)); menuItemConcurrentGcBeginEnd.setToolTipText(LocalisationHelper.getString("main_frame_menuitem_hint_concurrent_collection_begin_end")); - menuItemConcurrentGcBeginEnd.setIcon(ImageHelper.createMonoColoredImageIcon(ConcurrentGcBegionEndRenderer.CONCURRENT_COLLECTION_BEGIN, 20, 20)); + menuItemConcurrentGcBeginEnd.setIcon(ImageHelper.createMonoColoredImageIcon(ConcurrentGcBeginEndRenderer.CONCURRENT_COLLECTION_BEGIN, 20, 20)); menuItemConcurrentGcBeginEnd.setActionCommand(GCPreferences.CONCURRENT_COLLECTION_BEGIN_END); menuItemConcurrentGcBeginEnd.addActionListener(viewMenuController); menuBar.addToViewMenu(GCPreferences.CONCURRENT_COLLECTION_BEGIN_END, menuItemConcurrentGcBeginEnd); diff --git a/src/main/java/com/tagtraum/perf/gcviewer/imp/DataReaderIBM_J9_R28.java b/src/main/java/com/tagtraum/perf/gcviewer/imp/DataReaderIBM_J9_R28.java index 489dd487..8c520902 100644 --- a/src/main/java/com/tagtraum/perf/gcviewer/imp/DataReaderIBM_J9_R28.java +++ b/src/main/java/com/tagtraum/perf/gcviewer/imp/DataReaderIBM_J9_R28.java @@ -4,6 +4,7 @@ import java.io.InputStream; import java.io.LineNumberReader; import java.io.UnsupportedEncodingException; +import java.sql.Timestamp; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -76,11 +77,15 @@ public GCModel read() throws IOException { break; case SYS_START: assert eventNameStart == null : "eventNameStart was expected to be null, but was " + eventNameStart; - eventNameStart = handleSysStart(eventReader, startElement); + eventNameStart = handleSysStart(startElement); break; case AF_START: assert eventNameStart == null : "eventNameStart was expected to be null, but was " + eventNameStart; - eventNameStart = handleAfStart(eventReader, startElement); + eventNameStart = handleAfStart(); + break; + case CONCURRENT_COLLECTION_START: + assert eventNameStart == null : "eventNameStart was expected to be null, but was " + eventNameStart; + eventNameStart = handleConcurrentCollectionStart(); break; case GC_START: handleGcStart(eventReader, startElement, currentGcEvent, eventNameStart); @@ -154,9 +159,10 @@ else if (event.isEndElement()) { private GCEvent handleExclusiveStart(StartElement startElement) { GCEvent event = new GCEvent(); try { - event.setDateStamp(ZonedDateTime.of( - LocalDateTime.parse(getAttributeValue(startElement, "timestamp"), dateTimeFormatter), - ZoneId.systemDefault())); + String timestamp = getAttributeValue(startElement, "timestamp"); + LocalDateTime local = LocalDateTime.parse(timestamp, dateTimeFormatter); + event.setDateStamp(ZonedDateTime.of(local, ZoneId.systemDefault())); + event.setTimestamp(Timestamp.valueOf(local).getTime() / 1000); } catch (DateTimeParseException e) { if (getLogger().isLoggable(Level.WARNING)) getLogger().warning("line " + in.getLineNumber() + ": " + e.toString()); @@ -170,16 +176,17 @@ private void handleExclusiveEnd(StartElement startElement, GCEvent event) { event.setPause(NumberParser.parseDouble(getAttributeValue(startElement, "durationms")) / 1000); } - private String handleSysStart(XMLEventReader eventReader, StartElement startElement) throws XMLStreamException { + private String handleSysStart(StartElement startElement) { String reason = getAttributeValue(startElement, "reason"); return "sys " + (reason != null ? reason + " " : ""); } - private String handleAfStart(XMLEventReader eventReader, StartElement startElement) throws XMLStreamException { + private String handleAfStart() { return "af "; } - private void handleConcurrentCollectionStart(XMLEventReader eventReader, StartElement startElement) { + private String handleConcurrentCollectionStart() { + return "concurrent-collection-start "; } private void handleGcStart(XMLEventReader eventReader, StartElement startElement, GCEvent event, String eventNameStart) throws @@ -195,7 +202,7 @@ private void handleGcStart(XMLEventReader eventReader, StartElement startElement String currentElementName = ""; while (eventReader.hasNext() && !currentElementName.equals(GC_START)) { - + XMLEvent xmlEvent = eventReader.nextEvent(); if (xmlEvent.isStartElement()) { StartElement startEl = xmlEvent.asStartElement(); @@ -206,15 +213,20 @@ else if (startEl.getName().getLocalPart().equals("mem")) { switch (getAttributeValue(startEl, "type")) { case "nursery": GCEvent young = new GCEvent(); + young.setTimestamp(event.getTimestamp()); young.setType(Type.lookup("nursery")); setTotalAndPreUsed(young, startEl); event.add(young); break; case "tenure": - GCEvent tenured = new GCEvent(); - tenured.setType(Type.lookup("tenure")); - setTotalAndPreUsed(tenured, startEl); - event.add(tenured); + // scavenge prints tenure space but does not change it as it is young only + if(!typeName.contains("scavenge")) { + GCEvent tenured = new GCEvent(); + tenured.setTimestamp(event.getTimestamp()); + tenured.setType(Type.lookup("tenure")); + setTotalAndPreUsed(tenured, startEl); + event.add(tenured); + } break; // all other are ignored } @@ -230,7 +242,6 @@ else if (xmlEvent.isEndElement()) { private void handleGcEnd(XMLEventReader eventReader, GCEvent event) throws XMLStreamException { String currentElementName = ""; while (eventReader.hasNext() && !currentElementName.equals(GC_END)) { - XMLEvent xmlEvent = eventReader.nextEvent(); if (xmlEvent.isStartElement()) { StartElement startEl = xmlEvent.asStartElement(); @@ -243,7 +254,10 @@ else if (startEl.getName().getLocalPart().equals("mem")) { setPostUsed(event.getYoung(), startEl); break; case "tenure": - setPostUsed(event.getTenured(), startEl); + // scavenge prints tenure space but does not change it as it is young only + if(!event.getTypeAsString().contains("scavenge")) { + setPostUsed(event.getTenured(), startEl); + } break; // all other are ignored } @@ -273,11 +287,11 @@ private String getAttributeValue(StartElement event, String name) { if (attr != null) { value = attr.getValue(); } - + return value; } private int toKiloBytes(long bytes) { - return (int)Math.rint(bytes / (double)1024); + return (int) Math.rint(bytes / (double) 1024); } } diff --git a/src/main/java/com/tagtraum/perf/gcviewer/model/AbstractGCEvent.java b/src/main/java/com/tagtraum/perf/gcviewer/model/AbstractGCEvent.java index ff9a0ce3..d7ec11d7 100644 --- a/src/main/java/com/tagtraum/perf/gcviewer/model/AbstractGCEvent.java +++ b/src/main/java/com/tagtraum/perf/gcviewer/model/AbstractGCEvent.java @@ -46,7 +46,7 @@ public Iterator details() { public void add(T detail) { // most events have only one detail event if (details == null) { - details = new ArrayList(2); + details = new ArrayList(2); } details.add(detail); typeAsString += "; " + detail.getExtendedType().getName(); @@ -80,7 +80,7 @@ public void addPhase(AbstractGCEvent phase) { @Override protected Object clone() throws CloneNotSupportedException { - AbstractGCEvent clonedEvent = (AbstractGCEvent)super.clone(); + AbstractGCEvent clonedEvent = (AbstractGCEvent) super.clone(); if (getDatestamp() != null) { clonedEvent.setDateStamp(ZonedDateTime.from(this.getDatestamp())); } @@ -90,7 +90,7 @@ protected Object clone() throws CloneNotSupportedException { if (details != null) { List detailClones = new ArrayList<>(); for (T t : details) { - detailClones.add((T)t.clone()); + detailClones.add((T) t.clone()); } clonedEvent.details = detailClones; } @@ -102,7 +102,7 @@ protected Object clone() throws CloneNotSupportedException { public AbstractGCEvent cloneAndMerge(AbstractGCEvent otherEvent) { try { - AbstractGCEvent clonedEvent = (AbstractGCEvent)otherEvent.clone(); + AbstractGCEvent clonedEvent = (AbstractGCEvent) otherEvent.clone(); clonedEvent.setExtendedType(new ExtendedType(getExtendedType().getType(), getExtendedType().fullName + "+" + clonedEvent.getExtendedType().fullName)); clonedEvent.setPreUsed(clonedEvent.getPreUsed() + getPreUsed()); clonedEvent.setPostUsed(clonedEvent.getPostUsed() + getPostUsed()); @@ -115,7 +115,7 @@ public AbstractGCEvent cloneAndMerge(AbstractGCEvent otherEvent) { } public void setDateStamp(ZonedDateTime datestamp) { - this.datestamp = datestamp; + this.datestamp = datestamp; } public void setNumber(int number) { @@ -158,7 +158,7 @@ public int getNumber() { } public String getTypeAsString() { - return typeAsString; + return typeAsString; } public boolean isStopTheWorld() { @@ -176,6 +176,7 @@ public boolean isStopTheWorld() { /** * Returns the generation of the event including generation of detail events if present. + * * @return generation of event including generation of detail events */ public Generation getGeneration() { @@ -194,7 +195,7 @@ public Generation getGeneration() { generation = Generation.ALL; } else if (generationSet.size() == 1) { - generation = generationSet.iterator().next(); + generation = generationSet.iterator().next(); } else { // default @@ -247,7 +248,7 @@ public int getTotal() { public abstract void toStringBuffer(StringBuffer sb); @Override - public String toString() { + public String toString() { StringBuffer sb = new StringBuffer(128); toStringBuffer(sb); return sb.toString(); @@ -276,7 +277,8 @@ public boolean isSystem() { } public boolean isInc() { - return getExtendedType().getType() == GCEvent.Type.INC_GC; + Type type = getExtendedType().getType(); + return type == GCEvent.Type.INC_GC || type == Type.IBM_AF_SCAVENGE; } public boolean isConcurrent() { @@ -441,7 +443,7 @@ public int hashCode() { public String toString() { return fullName; } - } + } /** * Representation of an event type @@ -460,7 +462,7 @@ private Type(String name, Generation generation) { } private Type(String name, Generation generation, Concurrency concurrency) { - this(name, generation, concurrency, GcPattern.GC_MEMORY_PAUSE); + this(name, generation, concurrency, GcPattern.GC_MEMORY_PAUSE); } private Type(String name, Generation generation, Concurrency concurrency, GcPattern pattern) { @@ -494,7 +496,7 @@ public Concurrency getConcurrency() { } public GcPattern getPattern() { - return pattern; + return pattern; } public CollectionType getCollectionType() { @@ -544,11 +546,11 @@ public String toString() { public static final Type CMS_PERM = new Type("CMS Perm", Generation.PERM, Concurrency.SERIAL, GcPattern.GC_MEMORY); // Parnew (promotion failed) - public static final Type PAR_NEW_PROMOTION_FAILED = new Type("ParNew (promotion failed)", Generation.YOUNG, Concurrency.SERIAL); + public static final Type PAR_NEW_PROMOTION_FAILED = new Type("ParNew (promotion failed)", Generation.YOUNG, Concurrency.SERIAL); // CMS (concurrent mode failure / interrupted) - public static final Type CMS_CMF = new Type("CMS (concurrent mode failure)", Generation.TENURED, Concurrency.SERIAL); - public static final Type CMS_CMI = new Type("CMS (concurrent mode interrupted)", Generation.TENURED, Concurrency.SERIAL); + public static final Type CMS_CMF = new Type("CMS (concurrent mode failure)", Generation.TENURED, Concurrency.SERIAL); + public static final Type CMS_CMI = new Type("CMS (concurrent mode interrupted)", Generation.TENURED, Concurrency.SERIAL); // CMS (Concurrent Mark Sweep) Event Types public static final Type CMS_CONCURRENT_MARK_START = new Type("CMS-concurrent-mark-start", Generation.TENURED, Concurrency.CONCURRENT, GcPattern.GC); @@ -569,7 +571,7 @@ public String toString() { public static final Type ASCMS = new Type("ASCMS", Generation.TENURED); // Parnew (promotion failed) AdaptiveSizePolicy - public static final Type ASPAR_NEW_PROMOTION_FAILED = new Type("ASParNew (promotion failed)", Generation.YOUNG, Concurrency.SERIAL); + public static final Type ASPAR_NEW_PROMOTION_FAILED = new Type("ASParNew (promotion failed)", Generation.YOUNG, Concurrency.SERIAL); // CMS (concurrent mode failure / interrupted) AdaptiveSizePolicy public static final Type ASCMS_CMF = new Type("ASCMS (concurrent mode failure)", Generation.TENURED, Concurrency.SERIAL); @@ -708,9 +710,10 @@ public String toString() { public static final Type UJL_ZGC_HEAP_CAPACITY = new Type("Capacity", Generation.TENURED, Concurrency.SERIAL, GcPattern.GC_HEAP_MEMORY_PERCENTAGE); // IBM Types - // TODO: are scavenge always young only?? - public static final Type IBM_AF = new Type("af", Generation.YOUNG); public static final Type IBM_SYS = new Type("sys explicit", Generation.ALL); + public static final Type IBM_AF = new Type("af", Generation.YOUNG); + // scavenge is young only + // see https://www.ibm.com/support/knowledgecenter/SSYKE2_8.0.0/com.ibm.java.vm.80.doc/docs/mm_gc_pd_verbose_increment.html public static final Type IBM_AF_SCAVENGE = new Type("af scavenge", Generation.YOUNG); public static final Type IBM_AF_GLOBAL = new Type("af global", Generation.TENURED); public static final Type IBM_SYS_GLOBAL = new Type("sys global", Generation.ALL); @@ -720,7 +723,7 @@ public String toString() { public static final Type IBM_NURSERY = new Type("nursery", Generation.YOUNG); public static final Type IBM_TENURE = new Type("tenure", Generation.TENURED); - public static final Type IBM_CONCURRENT_COLLECTION_START = new Type("concurrent-collection-start", Generation.ALL, Concurrency.CONCURRENT); + public static final Type IBM_CONCURRENT_COLLECTION_START = new Type("concurrent-collection-start global", Generation.ALL, Concurrency.CONCURRENT); } diff --git a/src/main/java/com/tagtraum/perf/gcviewer/view/ModelChartImpl.java b/src/main/java/com/tagtraum/perf/gcviewer/view/ModelChartImpl.java index 58f86266..f1bb440f 100644 --- a/src/main/java/com/tagtraum/perf/gcviewer/view/ModelChartImpl.java +++ b/src/main/java/com/tagtraum/perf/gcviewer/view/ModelChartImpl.java @@ -57,7 +57,7 @@ public class ModelChartImpl extends JScrollPane implements ModelChart, ChangeLis private UsedTenuredRenderer usedTenuredRenderer; private UsedYoungRenderer usedYoungRenderer; private InitialMarkLevelRenderer initialMarkLevelRenderer; - private ConcurrentGcBegionEndRenderer concurrentGcLineRenderer; + private ConcurrentGcBeginEndRenderer concurrentGcLineRenderer; private boolean antiAlias; private TimeOffsetPanel timeOffsetPanel; private int lastViewPortWidth = 0; @@ -91,7 +91,7 @@ public ModelChartImpl() { chart.add(gcRectanglesRenderer, gridBagConstraints); incLineRenderer = new IncLineRenderer(this); chart.add(incLineRenderer, gridBagConstraints); - concurrentGcLineRenderer = new ConcurrentGcBegionEndRenderer(this); + concurrentGcLineRenderer = new ConcurrentGcBeginEndRenderer(this); chart.add(concurrentGcLineRenderer, gridBagConstraints); gcTimesRenderer = new GCTimesRenderer(this); chart.add(gcTimesRenderer, gridBagConstraints); diff --git a/src/main/java/com/tagtraum/perf/gcviewer/view/renderer/ConcurrentGcBegionEndRenderer.java b/src/main/java/com/tagtraum/perf/gcviewer/view/renderer/ConcurrentGcBeginEndRenderer.java similarity index 94% rename from src/main/java/com/tagtraum/perf/gcviewer/view/renderer/ConcurrentGcBegionEndRenderer.java rename to src/main/java/com/tagtraum/perf/gcviewer/view/renderer/ConcurrentGcBeginEndRenderer.java index e70c4f37..ff61603b 100644 --- a/src/main/java/com/tagtraum/perf/gcviewer/view/renderer/ConcurrentGcBegionEndRenderer.java +++ b/src/main/java/com/tagtraum/perf/gcviewer/view/renderer/ConcurrentGcBeginEndRenderer.java @@ -17,11 +17,11 @@ * @author Joerg Wuethrich *

created on: 30.10.2011

*/ -public class ConcurrentGcBegionEndRenderer extends ChartRenderer { +public class ConcurrentGcBeginEndRenderer extends ChartRenderer { public static final Paint CONCURRENT_COLLECTION_BEGIN = Color.CYAN; public static final Paint CONCURRENT_COLLECTION_END = Color.PINK; - public ConcurrentGcBegionEndRenderer(ModelChartImpl modelChart) { + public ConcurrentGcBeginEndRenderer(ModelChartImpl modelChart) { super(modelChart); setLinePaint(CONCURRENT_COLLECTION_BEGIN); } diff --git a/src/test/java/com/tagtraum/perf/gcviewer/imp/TestDataReaderIBM_J9_R27.java b/src/test/java/com/tagtraum/perf/gcviewer/imp/TestDataReaderIBM_J9_R27.java index 8f53fb3f..7ea7de69 100644 --- a/src/test/java/com/tagtraum/perf/gcviewer/imp/TestDataReaderIBM_J9_R27.java +++ b/src/test/java/com/tagtraum/perf/gcviewer/imp/TestDataReaderIBM_J9_R27.java @@ -1,7 +1,9 @@ package com.tagtraum.perf.gcviewer.imp; import static com.tagtraum.perf.gcviewer.UnittestHelper.toKiloBytes; +import static com.tagtraum.perf.gcviewer.imp.TestDataReaderIBM_J9_R28.verifyTimestamp; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.number.IsCloseTo.closeTo; import static org.junit.Assert.assertThat; @@ -23,6 +25,8 @@ */ public class TestDataReaderIBM_J9_R27 { + public static final String EXPECTED_ERROR_MESSAGE = "line 233: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[234,1]"; + private InputStream getInputStream(String fileName) throws IOException { return UnittestHelper.getResourceAsStream(FOLDER.IBM, fileName); } @@ -58,11 +62,13 @@ public void testFullHeaderWithAfGcs() throws Exception { assertThat("tenured before", event.getTenured().getPreUsed(), is(toKiloBytes(805306368 - 804158480))); assertThat("tenured after", event.getTenured().getPostUsed(), is(toKiloBytes(805306368 - 804158480))); - assertThat("timestamp 1", event.getTimestamp(), closeTo(0.0, 0.0001)); - assertThat("timestamp 2", model.get(1).getTimestamp(), closeTo(1.927, 0.0001)); - assertThat("timestamp 3", model.get(2).getTimestamp(), closeTo(3.982, 0.0001)); + verifyTimestamp("timestamp 1", event.getTimestamp(), "2014-09-24T15:57:32.116"); + verifyTimestamp("timestamp 2", model.get(1).getTimestamp(), "2014-09-24T15:57:34.043"); + verifyTimestamp("timestamp 3", model.get(2).getTimestamp(), "2014-09-24T15:57:36.098"); assertThat("number of errors", handler.getCount(), is(1)); + String message = handler.getLogRecords().get(0).getMessage(); + assertThat("missing close tag ", message, startsWith(EXPECTED_ERROR_MESSAGE)); } @Test diff --git a/src/test/java/com/tagtraum/perf/gcviewer/imp/TestDataReaderIBM_J9_R28.java b/src/test/java/com/tagtraum/perf/gcviewer/imp/TestDataReaderIBM_J9_R28.java index cc352209..ebe02e4a 100644 --- a/src/test/java/com/tagtraum/perf/gcviewer/imp/TestDataReaderIBM_J9_R28.java +++ b/src/test/java/com/tagtraum/perf/gcviewer/imp/TestDataReaderIBM_J9_R28.java @@ -8,15 +8,19 @@ import java.io.IOException; import java.io.InputStream; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.logging.Level; import com.tagtraum.perf.gcviewer.UnittestHelper; import com.tagtraum.perf.gcviewer.UnittestHelper.FOLDER; +import com.tagtraum.perf.gcviewer.model.AbstractGCEvent; import com.tagtraum.perf.gcviewer.model.GCEvent; import com.tagtraum.perf.gcviewer.model.GCModel; -import com.tagtraum.perf.gcviewer.model.GCResource; import com.tagtraum.perf.gcviewer.model.GcResourceFile; -import org.junit.Ignore; +import com.tagtraum.perf.gcviewer.model.GCResource; + import org.junit.Test; /** @@ -42,7 +46,7 @@ public void testAfScavenge() throws Exception { DataReader reader = getDataReader(gcResource); GCModel model = reader.read(); - + assertThat("model size", model.size(), is(2)); GCEvent event = (GCEvent) model.get(0); @@ -60,10 +64,15 @@ public void testAfScavenge() throws Exception { assertThat("tenured before", event.getTenured().getPreUsed(), is(toKiloBytes(402653184 - 401882552))); assertThat("tenured after", event.getTenured().getPostUsed(), is(toKiloBytes(402653184 - 401882552))); - assertThat("timestamp 1", event.getTimestamp(), closeTo(0.0, 0.0001)); - assertThat("timestamp 2", model.get(1).getTimestamp(), closeTo(1.272, 0.0001)); - assertThat("type", event.getTypeAsString(), equalTo("af scavenge; nursery; tenure")); + assertThat("type", event.getTypeAsString(), equalTo("af scavenge; nursery")); + assertThat("generation", event.getExtendedType().getGeneration(), is(AbstractGCEvent.Generation.YOUNG)); + assertThat("full", event.isFull(), is(false)); + assertThat("full", event.isInc(), is(true)); + + verifyTimestamp("first pause timestamp", model.getFirstPauseTimeStamp(), "2015-12-31T15:22:46.957"); + verifyTimestamp("event timestamp", event.getTimestamp(), "2015-12-31T15:22:46.957"); + verifyTimestamp("event timestamp 2", model.get(1).getTimestamp(), "2015-12-31T15:22:48.229"); assertThat("number of errors", handler.getCount(), is(0)); } @@ -84,6 +93,9 @@ public void testAfGlobal() throws Exception { assertThat("pause", event.getPause(), closeTo(1.255648, 0.0000001)); assertThat("type", event.getTypeAsString(), equalTo("af global; tenure")); + verifyTimestamp("event timestamp", event.getTimestamp(), "2016-08-09T14:58:58.343"); + verifyTimestamp("first pause timestamp", model.getFirstPauseTimeStamp(), "2016-08-09T14:58:58.343"); + assertThat("number of errors", handler.getCount(), is(0)); } @@ -103,6 +115,9 @@ public void testSysGlobal() throws Exception { assertThat("pause", event.getPause(), closeTo(0.097756, 0.0000001)); assertThat("type", event.getTypeAsString(), equalTo("sys explicit global; nursery; tenure")); + verifyTimestamp("event timestamp", event.getTimestamp(), "2015-12-31T15:23:00.646"); + verifyTimestamp("first pause timestamp", model.getFirstPauseTimeStamp(), "2015-12-31T15:23:00.646"); + assertThat("number of errors", handler.getCount(), is(0)); } @@ -121,7 +136,7 @@ public void testConcurrentMinimal() throws Exception { assertThat("number of errors", handler.getCount(), is(0)); } - @Test @Ignore + @Test public void testConcurrentCollection() throws Exception { TestLogHandler handler = new TestLogHandler(); handler.setLevel(Level.WARNING); @@ -131,9 +146,25 @@ public void testConcurrentCollection() throws Exception { DataReader reader = getDataReader(gcResource); GCModel model = reader.read(); + AbstractGCEvent event = model.get(0); assertThat("model size", model.size(), is(1)); - assertThat("duration", model.get(0).getPause(), closeTo(1.182375, 0.00000001)); + assertThat("duration", event.getPause(), closeTo(1.182375, 0.00000001)); + + assertThat("concurrency", event.getExtendedType().getConcurrency(), is(AbstractGCEvent.Concurrency.CONCURRENT)); + assertThat("generation", event.getExtendedType().getGeneration(), is(AbstractGCEvent.Generation.ALL)); + assertThat("full", event.isFull(), is(true)); + assertThat("full", event.isInc(), is(false)); + + verifyTimestamp("event timestamp", event.getTimestamp(), "2016-08-09T15:14:56.110"); + verifyTimestamp("first pause timestamp", model.getFirstPauseTimeStamp(), "2016-08-09T15:14:56.110"); + assertThat("number of errors", handler.getCount(), is(0)); } + public static void verifyTimestamp(String reason, double actual, String dateTime) { + DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; + LocalDateTime localDateTime = LocalDateTime.parse(dateTime, formatter); + double expected = Long.valueOf(Timestamp.valueOf(localDateTime).getTime()/1000).doubleValue(); + assertThat(reason, actual, is(expected)); + } }