Skip to content

Commit

Permalink
jifa: add unit tests
Browse files Browse the repository at this point in the history
Approximately 85% coverage.

Signed-off-by: Matthew Khouzam <[email protected]>
Change-Id: I246c271d7722c1559659c3c83aebba41e394db20
  • Loading branch information
MatthewKhouzam committed Jul 29, 2024
1 parent 61e4cca commit 53d474b
Show file tree
Hide file tree
Showing 10 changed files with 318 additions and 80 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*******************************************************************************
* Copyright (c) 2024 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/

package org.eclipse.tracecompass.incubator.jifa.core.tests.gclog;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;

import java.io.File;
import java.io.IOException;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.tracecompass.incubator.internal.jifa.core.gclog.GCTrace;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
* GC Trace test, basically checking the bridge between trace compass and jifa.
* Integration tests, it reads ALL the traces available.
*/
public class GCTraceTest {

private static final String TRACE_LOCATION = "src/org/eclipse/tracecompass/incubator/jifa/core/tests/gclog/res/11CMSGCParser.log";
private static final Set<String> EMPTY_TRACES = Set.of("src/org/eclipse/tracecompass/incubator/jifa/core/tests/gclog/res/11ZGCParser.log",
"src/org/eclipse/tracecompass/incubator/jifa/core/tests/gclog/res/17ZGCParser.log",
"src/org/eclipse/tracecompass/incubator/jifa/core/tests/gclog/res/8CMSPromotionFailed.log",
"src/org/eclipse/tracecompass/incubator/jifa/core/tests/gclog/res/8G1GCParserAdaptiveSize.log",
"src/org/eclipse/tracecompass/incubator/jifa/core/tests/gclog/res/8GenerationalGCInterleave.log");
private GCTrace fGcTrace;

/**
* Setup
*/
@Before
public void setUp() {
fGcTrace = new GCTrace();
}

/**
* Cleanup
*/
@After
public void tearDown() {
fGcTrace.dispose();
}

/**
* All traces are valid, some have no events.
*/
@Test
public void testValidateValidFile() {
for (File trace : new File("src/org/eclipse/tracecompass/incubator/jifa/core/tests/gclog/res/").listFiles()) {
IStatus status = fGcTrace.validate(null, trace.getAbsolutePath());
assertEquals("OK", status.getMessage());
assertEquals(trace.getPath(), 0, status.getCode());
}
}

/**
* Test an invalid trace
*/
@Test
public void testValidateInvalidFile() {
IStatus status = fGcTrace.validate(null, "src/org/eclipse/tracecompass/incubator/jifa/core/tests/gclog/badgc/not_a_gc.log");
assertEquals(IStatus.INFO, status.getSeverity());
assertEquals("Can not recognize file format. Please check if the file is a gc log.", status.getMessage());
}

/**
* Test init trace
*
* @throws TmfTraceException
* The trace initialization failed
* @throws IOException
* file parsing failed
*/
@Test
public void testInitTrace() throws TmfTraceException, IOException {
fGcTrace.initTrace(null, TRACE_LOCATION, ITmfEvent.class);
assertEquals(TRACE_LOCATION, fGcTrace.getPath());
}

/**
* Test Get Current Location
*/
@Test
public void testGetCurrentLocation() {
ITmfLocation location = fGcTrace.getCurrentLocation();
assertEquals(0L, location.getLocationInfo());
}

/**
* Test seek
*
* @throws TmfTraceException
* the trace failed to load
*/
@Test
public void testSeekEventWithLocation() throws TmfTraceException {
fGcTrace.initTrace(null, TRACE_LOCATION, null);
assertNotNull(fGcTrace.seekEvent(new TmfLongLocation(0)));
}

/**
* Test seeking at a ratio
*
* @throws TmfTraceException
* the trace failed to load
*/
@Test
public void testSeekEventWithRatio() throws TmfTraceException {
fGcTrace.initTrace(null, TRACE_LOCATION, null);
ITmfContext a = fGcTrace.seekEvent(new TmfLongLocation(0));
ITmfContext b = fGcTrace.seekEvent(0.5);
assertNotEquals(a, b);

}

/**
* Test parsing every event
*
* @throws TmfTraceException
* the trace failed to load
*/
@Test
public void testParseEvent() throws TmfTraceException {
File root = new File("src/org/eclipse/tracecompass/incubator/jifa/core/tests/gclog/res/");
for (File trace : root.listFiles()) {
fGcTrace.dispose();
fGcTrace = new GCTrace();
fGcTrace.initTrace(null, trace.getAbsolutePath(), ITmfEvent.class);
assertEquals(fGcTrace.getNbEvents(), 0L);
fGcTrace.readEnd();
if (!EMPTY_TRACES.contains(trace.getPath())) {
assertNotEquals(trace.getPath(), fGcTrace.getNbEvents(), 0L);
} else {
assertEquals(trace.getPath(), fGcTrace.getNbEvents(), 0L);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
I am the very model of a modern Major-General
I've information vegetable, animal, and mineral
I know the kings of England, and I quote the fights historical
From Marathon to Waterloo, in order categorical
I'm very well acquainted, too, with matters mathematical
I understand equations, both the simple and quadratical
About binomial theorem I am teeming with a lot o' news
With many cheerful facts about the square of the hypotenuse.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ public class GCTrace extends TmfTrace {

@Override
public IStatus validate(@Nullable IProject project, @Nullable String path) {
return new File(path).canRead() ? new TraceValidationStatus(10, "syslog") : new Status(IStatus.INFO, getClass(), "not a gc log"); //$NON-NLS-1$ //$NON-NLS-2$
try (BufferedReader br = new BufferedReader(new FileReader(new File(path)))) {
new GCLogParserFactory().getParser(br);
} catch (IllegalStateException | IOException e) {
return new Status(IStatus.INFO, getClass(), e.getMessage());
}
return new TraceValidationStatus(10, this.getClass().getName());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,9 @@ public void putEvent(GCEvent event) {

public void addPhase(GCEvent parent, GCEvent phase) {
allEvents.add(phase);
parent.addPhase(phase);
if (parent != null) {
parent.addPhase(phase);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -358,6 +359,26 @@ public String getText() {
public void setText(String text) {
this.text = text;
}

@Override
public int hashCode() {
return Objects.hash(text);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
VmOptionVo other = (VmOptionVo) obj;
return Objects.equals(text, other.text);
}
}

public static class VmOptionResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ public final GCModel parse(BufferedReader br) throws TmfTraceException {
doParseLine(line);
}
} catch (Exception e) {
Activator.getInstance().logInfo(String.format("fail to parse \"{}\", {}", line, e.getMessage()));
Activator.getInstance().logInfo(String.format("fail to parse \"%s\", %s", line, e.getMessage()));
}
}
endParsing();
} catch (Exception e) {
Activator.getInstance().logInfo(String.format("fail to parse \"{}\", {}", line, e.getMessage()));
Activator.getInstance().logInfo(String.format("fail to parse \"%s\", %s", line, e.getMessage()));
}

return model;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public GCModel parse() throws TmfTraceException {

return model;
} catch (IOException | TmfTraceException e) {
Activator.getInstance().logInfo(String.format("fail to parse gclog {}: {}", file.getName(), e.getMessage()));
Activator.getInstance().logInfo(String.format("fail to parse gclog {0}: {1}", file.getName(), e.getMessage()));
throw new TmfTraceException(e.getMessage(), e);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ private static void parseConcurrentCyclePhase(AbstractGCLogParser parser, ParseR
} else {
parent = model.getLastEventOfType(G1_CONCURRENT_CYCLE);
}
GCEvent phaseStart = parent.getLastPhaseOfType(phaseType);
GCEvent phaseStart = parent == null ? null : parent.getLastPhaseOfType(phaseType);
if (phaseStart == null) {
phase.setEventType(phaseType);
model.addPhase(parent, phase);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
********************************************************************************/
package org.eclipse.tracecompass.incubator.internal.jifa.core.gclog.vo;

import java.util.Objects;

public class MemoryStatistics {
private MemoryStatisticsItem young;
private MemoryStatisticsItem old;
Expand All @@ -25,7 +27,7 @@ public static class MemoryStatisticsItem {
private long usedAvgAfterFullGC;
private long usedAvgAfterOldGC;

public MemoryStatisticsItem(long average, long max, long avgPostGC, long avgOldGC) {
public MemoryStatisticsItem(long average, long max, long avgOldGC, long avgPostGC) {
capacityAvg = average;
usedMax = max;
usedAvgAfterFullGC = avgPostGC;
Expand Down Expand Up @@ -91,6 +93,26 @@ public long getUsedAvgAfterOldGC() {
public void setUsedAvgAfterOldGC(long usedAvgAfterOldGC) {
this.usedAvgAfterOldGC = usedAvgAfterOldGC;
}

@Override
public int hashCode() {
return Objects.hash(capacityAvg, usedAvgAfterFullGC, usedAvgAfterOldGC, usedMax);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
MemoryStatisticsItem other = (MemoryStatisticsItem) obj;
return capacityAvg == other.capacityAvg && usedAvgAfterFullGC == other.usedAvgAfterFullGC && usedAvgAfterOldGC == other.usedAvgAfterOldGC && usedMax == other.usedMax;
}
}

/**
Expand Down
Loading

0 comments on commit 53d474b

Please sign in to comment.