Skip to content

Commit

Permalink
Refactor + adding UseConcMarkSweepGC test
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosroman committed Dec 20, 2023
1 parent 90835f9 commit 2484b72
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 148 deletions.
72 changes: 6 additions & 66 deletions src/test/java/org/datadog/jmxfetch/TestCommon.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package org.datadog.jmxfetch;

import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
Expand All @@ -19,24 +15,24 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;

import org.junit.After;
import org.junit.BeforeClass;

import org.datadog.jmxfetch.reporter.ConsoleReporter;
import org.datadog.jmxfetch.reporter.Reporter;
import org.datadog.jmxfetch.util.CustomLogger;
import org.datadog.jmxfetch.util.MetricsAssert;
import org.datadog.jmxfetch.util.LogLevel;
import org.junit.After;
import org.junit.BeforeClass;

final class ConfigUtil {
public static Path writeConfigYamlToTemp(String content, String yamlName) throws IOException {
Expand Down Expand Up @@ -238,62 +234,6 @@ protected List<Map<String, Object>> getServiceChecks() {
return ((ConsoleReporter) appConfig.getReporter()).getServiceChecks();
}

public static void assertMetric(
String name,
Number value,
Number lowerBound,
Number upperBound,
List<String> commonTags,
List<String> additionalTags,
int countTags,
String metricType,
List<Map<String, Object>> actualMetrics) {
List<String> tags = new ArrayList<>(commonTags);
tags.addAll(additionalTags);

for (Map<String, Object> m : actualMetrics) {
String mName = (String) (m.get("name"));
Double mValue = (Double) (m.get("value"));
Set<String> mTags = new HashSet<>(Arrays.asList((String[]) (m.get("tags"))));

if (mName.equals(name)) {

if (!value.equals(-1)) {
assertEquals((Double) value.doubleValue(), mValue);
} else if (!lowerBound.equals(-1) || !upperBound.equals(-1)) {
assertTrue(mValue > (Double) lowerBound.doubleValue());
assertTrue(mValue < (Double) upperBound.doubleValue());
}

if (countTags != -1) {
assertEquals(countTags, mTags.size());
}
for (String t : tags) {
assertThat(mTags, hasItem(t));
}

if (metricType != null) {
assertEquals(metricType, m.get("type"));
}
// Brand the metric
m.put("tested", true);

return;
}
}
fail(
"Metric assertion failed (name: "
+ name
+ ", value: "
+ value
+ ", tags: "
+ tags
+ ", #tags: "
+ countTags
+ ").");

}

/**
* Assert that a specific metric was collected. Brand the metric so we can easily know which
* metric have/have not been tested
Expand All @@ -317,7 +257,7 @@ public void assertMetric(
List<String> additionalTags,
int countTags,
String metricType) {
assertMetric(name, value, lowerBound, upperBound, commonTags, additionalTags, countTags, metricType, this.metrics);
MetricsAssert.assertMetric(name, value, lowerBound, upperBound, commonTags, additionalTags, countTags, metricType, this.metrics);
}

public void assertMetric(
Expand Down
127 changes: 45 additions & 82 deletions src/test/java/org/datadog/jmxfetch/TestGCMetrics.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.datadog.jmxfetch;

import static org.datadog.jmxfetch.util.MetricsAssert.assertDomainPresent;
import static org.datadog.jmxfetch.util.MetricsAssert.isDomainPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

Expand All @@ -20,6 +19,7 @@
import org.datadog.jmxfetch.reporter.ConsoleReporter;
import org.datadog.jmxfetch.util.server.MisbehavingJMXServer;
import org.datadog.jmxfetch.util.server.SimpleAppContainer;
import org.datadog.jmxfetch.util.MetricsAssert;

@Slf4j
public class TestGCMetrics extends TestCommon {
Expand All @@ -42,25 +42,7 @@ public void testJMXDirectBasic() throws Exception {
public void testDefaultOldGC() throws IOException {
try (final MisbehavingJMXServer server = new MisbehavingJMXServer(MisbehavingJMXServer.DEFAULT_RMI_PORT, MisbehavingJMXServer.DEFAULT_CONTROL_PORT,
MisbehavingJMXServer.DEFAULT_SUPERVISOR_PORT)) {
server.start();
this.initApplicationWithYamlLines(
"init_config:",
" is_jmx: true",
"",
"instances:",
" - name: jmxint_container",
" host: " + server.getIp(),
" collect_default_jvm_metrics: true",
" max_returned_metrics: 300000",
" port: " + server.getRMIPort());
// Run one iteration first
this.app.doIteration();
// And then pull get the metrics or else reporter does not have correct number of metrics
((ConsoleReporter) appConfig.getReporter()).getMetrics();

// Actual iteration we care about
this.app.doIteration();
final List<Map<String, Object>> actualMetrics = ((ConsoleReporter) appConfig.getReporter()).getMetrics();
final List<Map<String, Object>> actualMetrics = startAngGetMetrics(server, false);
List<String> gcGenerations = Arrays.asList(
"G1 Old Generation",
"G1 Young Generation");
Expand All @@ -74,25 +56,7 @@ public void testDefaultNewGCMetricsUseParallelGC() throws IOException {
try (final MisbehavingJMXServer server = new MisbehavingJMXServer(
MisbehavingJMXServer.JDK_11,
"-XX:+UseParallelGC -Xmx128M -Xms128M")) {
server.start();
this.initApplicationWithYamlLines("init_config:",
" is_jmx: true",
" new_gc_metrics: true",
"",
"instances:",
" - name: jmxint_container",
" host: " + server.getIp(),
" collect_default_jvm_metrics: true",
" max_returned_metrics: 300000",
" port: " + server.getRMIPort());
// Run one iteration first
this.app.doIteration();
// And then pull get the metrics or else reporter does not have correct number of metrics
((ConsoleReporter) appConfig.getReporter()).getMetrics();

// Actual iteration we care about
this.app.doIteration();
final List<Map<String, Object>> actualMetrics = ((ConsoleReporter) appConfig.getReporter()).getMetrics();
final List<Map<String, Object>> actualMetrics = startAngGetMetrics(server, true);
assertThat(actualMetrics, hasSize(13));
assertGCMetric(actualMetrics, "jvm.gc.minor_collection_count", "PS Scavenge", "counter");
assertGCMetric(actualMetrics, "jvm.gc.minor_collection_time", "PS Scavenge", "counter");
Expand All @@ -101,77 +65,76 @@ public void testDefaultNewGCMetricsUseParallelGC() throws IOException {
}
}

@Test
public void testDefaultNewGCMetricsUseConcMarkSweepGC() throws IOException {
try (final MisbehavingJMXServer server = new MisbehavingJMXServer(
MisbehavingJMXServer.JDK_11,
"-XX:+UseConcMarkSweepGC -Xmx128M -Xms128M")) {
final List<Map<String, Object>> actualMetrics = startAngGetMetrics(server, true);
assertThat(actualMetrics, hasSize(13));
assertGCMetric(actualMetrics, "jvm.gc.minor_collection_count", "ParNew", "counter");
assertGCMetric(actualMetrics, "jvm.gc.minor_collection_time", "ParNew", "counter");
assertGCMetric(actualMetrics, "jvm.gc.major_collection_count", "ConcurrentMarkSweep", "counter");
assertGCMetric(actualMetrics, "jvm.gc.major_collection_time", "ConcurrentMarkSweep", "counter");
}
}

@Test
public void testDefaultNewGCMetricsUseG1GC() throws IOException {
try (final MisbehavingJMXServer server = new MisbehavingJMXServer(
MisbehavingJMXServer.JDK_17,
"-XX:+UseG1GC -Xmx128M -Xms128M")) {
server.start();
this.initApplicationWithYamlLines(
"init_config:",
" is_jmx: true",
" new_gc_metrics: true",
"",
"instances:",
" - name: jmxint_container",
" host: " + server.getIp(),
" collect_default_jvm_metrics: true",
" max_returned_metrics: 300000",
" port: " + server.getRMIPort());
// Run one iteration first
this.app.doIteration();
// And then pull get the metrics or else reporter does not have correct number of metrics
((ConsoleReporter) appConfig.getReporter()).getMetrics();

// Actual iteration we care about
this.app.doIteration();
final List<Map<String, Object>> actualMetrics = ((ConsoleReporter) appConfig.getReporter()).getMetrics();
final List<Map<String, Object>> actualMetrics = startAngGetMetrics(server, true);
assertThat(actualMetrics, hasSize(13));
final List<String> gcYoungGenerations = Collections.singletonList(
"G1 Young Generation");
assertGCMetric(actualMetrics, "jvm.gc.minor_collection_count", "G1 Young Generation", "counter");
assertGCMetric(actualMetrics, "jvm.gc.minor_collection_time", "G1 Young Generation", "counter");
assertGCMetric(actualMetrics, "jvm.gc.major_collection_count", "G1 Old Generation", "counter");
assertGCMetric(actualMetrics, "jvm.gc.major_collection_time", "G1 Old Generation", "counter");
}
}

@Test
public void testDefaultNewGCMetricsUseZGC() throws IOException {
try (final MisbehavingJMXServer server = new MisbehavingJMXServer(
MisbehavingJMXServer.JDK_17,
"-XX:+UseZGC -Xmx128M -Xms128M")) {
server.start();
this.initApplicationWithYamlLines("init_config:",
" is_jmx: true",
" new_gc_metrics: true",
"",
"instances:",
" - name: jmxint_container",
" host: " + server.getIp(),
" collect_default_jvm_metrics: true",
" max_returned_metrics: 300000",
" port: " + server.getRMIPort());
// Run one iteration first
this.app.doIteration();
// And then pull get the metrics or else reporter does not have correct number of metrics
((ConsoleReporter) appConfig.getReporter()).getMetrics();

// Actual iteration we care about
this.app.doIteration();
final List<Map<String, Object>> actualMetrics = ((ConsoleReporter) appConfig.getReporter()).getMetrics();
final List<Map<String, Object>> actualMetrics = startAngGetMetrics(server, true);
assertThat(actualMetrics, hasSize(13));
assertGCMetric(actualMetrics, "jvm.gc.zgc_pauses_collection_count", "ZGC Pauses", "counter");
assertGCMetric(actualMetrics, "jvm.gc.zgc_pauses_collection_time", "ZGC Pauses", "counter");
assertGCMetric(actualMetrics, "jvm.gc.zgc_cycles_collection_count", "ZGC Cycles", "counter");
assertGCMetric(actualMetrics, "jvm.gc.zgc_cycles_collection_time", "ZGC Cycles", "counter");
}
}

private List<Map<String, Object>> startAngGetMetrics(final MisbehavingJMXServer server, final boolean newGCMetrics) throws IOException {
server.start();
this.initApplicationWithYamlLines(
"init_config:",
" is_jmx: true",
" new_gc_metrics: " + newGCMetrics,
"",
"instances:",
" - name: jmxint_container",
" host: " + server.getIp(),
" collect_default_jvm_metrics: true",
" max_returned_metrics: 300000",
" port: " + server.getRMIPort());
// Run one iteration first
this.app.doIteration();
// And then pull get the metrics or else reporter does not have correct number of metrics
((ConsoleReporter) appConfig.getReporter()).getMetrics();

// Actual iteration we care about
this.app.doIteration();
return ((ConsoleReporter) appConfig.getReporter()).getMetrics();
}

private static void assertGCMetric(final List<Map<String, Object>> actualMetrics,
final String expectedMetric,
final String gcGeneration,
final String metricType) {
TestCommon.assertMetric(
MetricsAssert.assertMetric(
expectedMetric,
-1,
-1,
Expand Down
66 changes: 66 additions & 0 deletions src/test/java/org/datadog/jmxfetch/util/MetricsAssert.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,81 @@
package org.datadog.jmxfetch.util;

import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.management.MBeanServerConnection;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MetricsAssert {

public static void assertMetric(
String name,
Number value,
Number lowerBound,
Number upperBound,
List<String> commonTags,
List<String> additionalTags,
int countTags,
String metricType,
List<Map<String, Object>> actualMetrics) {
List<String> tags = new ArrayList<>(commonTags);
tags.addAll(additionalTags);

for (Map<String, Object> m : actualMetrics) {
String mName = (String) (m.get("name"));
Double mValue = (Double) (m.get("value"));
Set<String> mTags = new HashSet<>(Arrays.asList((String[]) (m.get("tags"))));

if (mName.equals(name)) {

if (!value.equals(-1)) {
assertEquals((Double) value.doubleValue(), mValue);
} else if (!lowerBound.equals(-1) || !upperBound.equals(-1)) {
assertTrue(mValue > (Double) lowerBound.doubleValue());
assertTrue(mValue < (Double) upperBound.doubleValue());
}

if (countTags != -1) {
assertEquals(countTags, mTags.size());
}
for (String t : tags) {
assertThat(mTags, hasItem(t));
}

if (metricType != null) {
assertEquals(metricType, m.get("type"));
}
// Brand the metric
m.put("tested", true);

return;
}
}
fail(
"Metric assertion failed (name: "
+ name
+ ", value: "
+ value
+ ", tags: "
+ tags
+ ", #tags: "
+ countTags
+ ").");

}

public static void assertDomainPresent(final String domain, final MBeanServerConnection mbs){
assertThat(String.format("Could not find domain '%s'", domain),
isDomainPresent(domain, mbs), equalTo(true));
Expand Down

0 comments on commit 2484b72

Please sign in to comment.