Move awaitGC to common utility package

This commit is contained in:
Tyler Benson 2019-01-24 17:46:51 -08:00
parent b3ad700b34
commit 03bcdc97cc
17 changed files with 39 additions and 59 deletions

View File

@ -19,6 +19,7 @@ dependencies {
testCompile deps.opentracing testCompile deps.opentracing
testCompile project(':dd-java-agent:testing') testCompile project(':dd-java-agent:testing')
testCompile project(':utils:gc-utils')
instrumentationMuzzle sourceSets.main.output instrumentationMuzzle sourceSets.main.output
instrumentationMuzzle configurations.compile instrumentationMuzzle configurations.compile

View File

@ -1,7 +1,8 @@
package datadog.trace.agent.tooling package datadog.trace.agent.tooling
import datadog.trace.agent.test.TestUtils
import datadog.trace.bootstrap.WeakMap import datadog.trace.bootstrap.WeakMap
import datadog.trace.util.gc.GCUtils
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification import spock.lang.Specification
@ -47,7 +48,7 @@ class WeakConcurrentSupplierTest extends Specification {
when: when:
def supplierRef = new WeakReference(supplier) def supplierRef = new WeakReference(supplier)
supplier = null supplier = null
TestUtils.awaitGC(supplierRef) GCUtils.awaitGC(supplierRef)
then: then:
ref.get() == null ref.get() == null
@ -68,7 +69,7 @@ class WeakConcurrentSupplierTest extends Specification {
when: when:
def mapRef = new WeakReference(map) def mapRef = new WeakReference(map)
map = null map = null
TestUtils.awaitGC(mapRef) GCUtils.awaitGC(mapRef)
then: then:
ref.get() == null ref.get() == null
@ -84,7 +85,7 @@ class WeakConcurrentSupplierTest extends Specification {
setup: setup:
def key = new Object() def key = new Object()
map.put(key, "value") map.put(key, "value")
TestUtils.awaitGC() GCUtils.awaitGC()
expect: expect:
map.size() == 1 map.size() == 1
@ -92,7 +93,7 @@ class WeakConcurrentSupplierTest extends Specification {
when: when:
def keyRef = new WeakReference(key) def keyRef = new WeakReference(key)
key = null key = null
TestUtils.awaitGC(keyRef) GCUtils.awaitGC(keyRef)
if (name == "WeakConcurrent") { if (name == "WeakConcurrent") {
// Sleep enough time for cleanup thread to get scheduled. // Sleep enough time for cleanup thread to get scheduled.

View File

@ -92,6 +92,7 @@ modifyPom {
dependencies { dependencies {
testCompile project(':dd-trace-api') testCompile project(':dd-trace-api')
testCompile project(':dd-trace-ot') testCompile project(':dd-trace-ot')
testCompile project(':utils:gc-utils')
testCompile deps.opentracingMock testCompile deps.opentracingMock
testCompile deps.testLogging testCompile deps.testLogging

View File

@ -4,6 +4,7 @@ import datadog.test.ClassToInstrument
import datadog.test.ClassToInstrumentChild import datadog.test.ClassToInstrumentChild
import datadog.trace.agent.test.IntegrationTestUtils import datadog.trace.agent.test.IntegrationTestUtils
import datadog.trace.api.Trace import datadog.trace.api.Trace
import datadog.trace.util.gc.GCUtils
import spock.lang.Specification import spock.lang.Specification
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@ -39,7 +40,7 @@ class ClassLoadingTest extends Specification {
loader.loadClass(ClassToInstrument.getName()) loader.loadClass(ClassToInstrument.getName())
loader = null loader = null
IntegrationTestUtils.awaitGC(ref) GCUtils.awaitGC(ref)
then: then:
null == ref.get() null == ref.get()

View File

@ -11,7 +11,6 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
@ -187,20 +186,6 @@ public class IntegrationTestUtils {
return (String[]) f.get(null); return (String[]) f.get(null);
} }
public static void awaitGC() {
Object obj = new Object();
final WeakReference<Object> ref = new WeakReference<>(obj);
obj = null;
awaitGC(ref);
}
public static void awaitGC(final WeakReference<?> ref) {
while (ref.get() != null) {
System.gc();
System.runFinalization();
}
}
/** /**
* On a separate JVM, run the main method for a given class. * On a separate JVM, run the main method for a given class.
* *

View File

@ -19,7 +19,6 @@ import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.ServerSocket; import java.net.ServerSocket;
@ -218,20 +217,6 @@ public class TestUtils {
} }
} }
public static void awaitGC() {
Object obj = new Object();
final WeakReference<Object> ref = new WeakReference<>(obj);
obj = null;
awaitGC(ref);
}
public static void awaitGC(final WeakReference<?> ref) {
while (ref.get() != null) {
System.gc();
System.runFinalization();
}
}
public static ClassPath getTestClasspath() { public static ClassPath getTestClasspath() {
return testClasspath; return testClasspath;
} }
@ -245,7 +230,7 @@ public class TestUtils {
} }
try { try {
return ClassPath.from(testClassLoader); return ClassPath.from(testClassLoader);
} catch (IOException e) { } catch (final IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@ -254,15 +239,15 @@ public class TestUtils {
* Parse JVM classpath and return ClassLoader containing all classpath entries. Inspired by Guava. * Parse JVM classpath and return ClassLoader containing all classpath entries. Inspired by Guava.
*/ */
private static ClassLoader buildJavaClassPathClassLoader() { private static ClassLoader buildJavaClassPathClassLoader() {
ImmutableList.Builder<URL> urls = ImmutableList.builder(); final ImmutableList.Builder<URL> urls = ImmutableList.builder();
for (String entry : Splitter.on(PATH_SEPARATOR.value()).split(JAVA_CLASS_PATH.value())) { for (final String entry : Splitter.on(PATH_SEPARATOR.value()).split(JAVA_CLASS_PATH.value())) {
try { try {
try { try {
urls.add(new File(entry).toURI().toURL()); urls.add(new File(entry).toURI().toURL());
} catch (SecurityException e) { // File.toURI checks to see if the file is a directory } catch (final SecurityException e) { // File.toURI checks to see if the file is a directory
urls.add(new URL("file", null, new File(entry).getAbsolutePath())); urls.add(new URL("file", null, new File(entry).getAbsolutePath()));
} }
} catch (MalformedURLException e) { } catch (final MalformedURLException e) {
System.err.println( System.err.println(
String.format( String.format(
"Error injecting bootstrap jar: Malformed classpath entry: %s. %s", entry, e)); "Error injecting bootstrap jar: Malformed classpath entry: %s. %s", entry, e));

View File

@ -3,6 +3,7 @@ package context
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.TestUtils import datadog.trace.agent.test.TestUtils
import datadog.trace.api.Config import datadog.trace.api.Config
import datadog.trace.util.gc.GCUtils
import net.bytebuddy.agent.ByteBuddyAgent import net.bytebuddy.agent.ByteBuddyAgent
import net.bytebuddy.utility.JavaModule import net.bytebuddy.utility.JavaModule
import spock.lang.Requires import spock.lang.Requires
@ -101,7 +102,7 @@ class FieldBackedProviderTest extends AgentTestRunner {
final int count = keyValue.get().incrementContextCount() final int count = keyValue.get().incrementContextCount()
WeakReference<KeyClass> instanceRef = new WeakReference(keyValue.get()) WeakReference<KeyClass> instanceRef = new WeakReference(keyValue.get())
keyValue.set(null) keyValue.set(null)
TestUtils.awaitGC(instanceRef) GCUtils.awaitGC(instanceRef)
then: then:
instanceRef.get() == null instanceRef.get() == null

View File

@ -1,9 +1,9 @@
package muzzle; package muzzle;
import datadog.trace.agent.test.TestUtils;
import datadog.trace.agent.tooling.muzzle.Reference; import datadog.trace.agent.tooling.muzzle.Reference;
import datadog.trace.agent.tooling.muzzle.ReferenceCreator; import datadog.trace.agent.tooling.muzzle.ReferenceCreator;
import datadog.trace.agent.tooling.muzzle.ReferenceMatcher; import datadog.trace.agent.tooling.muzzle.ReferenceMatcher;
import datadog.trace.util.gc.GCUtils;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
@ -26,7 +26,7 @@ public class MuzzleWeakReferenceTest {
final ReferenceMatcher refMatcher = new ReferenceMatcher(refs); final ReferenceMatcher refMatcher = new ReferenceMatcher(refs);
refMatcher.getMismatchedReferenceSources(loader); refMatcher.getMismatchedReferenceSources(loader);
loader = null; loader = null;
TestUtils.awaitGC(clRef); GCUtils.awaitGC(clRef);
return clRef.get() == null; return clRef.get() == null;
} }
} }

View File

@ -32,6 +32,8 @@ dependencies {
compile deps.groovy compile deps.groovy
testCompile project(':utils:gc-utils')
// test instrumenting java 1.1 bytecode // test instrumenting java 1.1 bytecode
testCompile group: 'net.sf.jt400', name: 'jt400', version: '6.1' testCompile group: 'net.sf.jt400', name: 'jt400', version: '6.1'

View File

@ -38,6 +38,7 @@ dependencies {
testImplementation deps.autoservice testImplementation deps.autoservice
testCompile project(":dd-java-agent:testing") testCompile project(":dd-java-agent:testing")
testCompile project(':utils:gc-utils')
testCompile group: 'org.assertj', name: 'assertj-core', version: '2.9.+' testCompile group: 'org.assertj', name: 'assertj-core', version: '2.9.+'
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.19.0' testCompile group: 'org.mockito', name: 'mockito-core', version: '2.19.0'
testCompile group: 'org.objenesis', name: 'objenesis', version: '2.6' testCompile group: 'org.objenesis', name: 'objenesis', version: '2.6'

View File

@ -1,8 +1,9 @@
package datadog.opentracing package datadog.opentracing
import datadog.trace.agent.test.TestUtils
import datadog.trace.api.Config import datadog.trace.api.Config
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.util.gc.GCUtils
import spock.lang.Specification import spock.lang.Specification
import spock.lang.Subject import spock.lang.Subject
import spock.lang.Timeout import spock.lang.Timeout
@ -113,7 +114,7 @@ class PendingTraceTest extends Specification {
when: when:
def childRef = new WeakReference<>(child) def childRef = new WeakReference<>(child)
child = null child = null
TestUtils.awaitGC(childRef) GCUtils.awaitGC(childRef)
while (trace.pendingReferenceCount.get() > 0) { while (trace.pendingReferenceCount.get() > 0) {
trace.clean() trace.clean()
} }

View File

@ -3,9 +3,9 @@ package datadog.opentracing.scopemanager
import datadog.opentracing.DDSpan import datadog.opentracing.DDSpan
import datadog.opentracing.DDSpanContext import datadog.opentracing.DDSpanContext
import datadog.opentracing.DDTracer import datadog.opentracing.DDTracer
import datadog.trace.agent.test.TestUtils
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.context.ScopeListener import datadog.trace.context.ScopeListener
import datadog.trace.util.gc.GCUtils
import io.opentracing.Scope import io.opentracing.Scope
import io.opentracing.Span import io.opentracing.Span
import io.opentracing.noop.NoopSpan import io.opentracing.noop.NoopSpan
@ -154,7 +154,7 @@ class ScopeManagerTest extends Specification {
continuation.activate() continuation.activate()
if (forceGC) { if (forceGC) {
continuation = null // Continuation references also hold up traces. continuation = null // Continuation references also hold up traces.
TestUtils.awaitGC() // The goal here is to make sure that continuation DOES NOT get GCed GCUtils.awaitGC() // The goal here is to make sure that continuation DOES NOT get GCed
while (((DDSpanContext) scope.span().context()).trace.clean()) { while (((DDSpanContext) scope.span().context()).trace.clean()) {
} }
} }
@ -204,7 +204,7 @@ class ScopeManagerTest extends Specification {
if (forceGC) { if (forceGC) {
def continuationRef = new WeakReference<>(continuation) def continuationRef = new WeakReference<>(continuation)
continuation = null // Continuation references also hold up traces. continuation = null // Continuation references also hold up traces.
TestUtils.awaitGC(continuationRef) GCUtils.awaitGC(continuationRef)
while (traceCount.get() == 0) { while (traceCount.get() == 0) {
// wait until trace count increments or timeout expires // wait until trace count increments or timeout expires
} }

View File

@ -5,14 +5,13 @@ dependencies {
annotationProcessor deps.autoservice annotationProcessor deps.autoservice
implementation deps.autoservice implementation deps.autoservice
compile project(':dd-java-agent:agent-bootstrap')
compile project(':dd-trace-api') compile project(':dd-trace-api')
compile deps.jackson
compile deps.slf4j compile deps.slf4j
// any higher versions seems to break ES tests with this exception: compile deps.jackson
// java.lang.NoSuchMethodError: com.fasterxml.jackson.dataformat.smile.SmileGenerator.getOutputContext() compile group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.8.16'
compile group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.8.14'
compile project(':utils:gc-utils')
// Spock uses that for mocking // Spock uses that for mocking
testCompile deps.bytebuddy testCompile deps.bytebuddy

View File

@ -5,6 +5,7 @@ import datadog.trace.tracer.sampling.AllSampler
import datadog.trace.tracer.writer.AgentWriter import datadog.trace.tracer.writer.AgentWriter
import datadog.trace.tracer.writer.SampleRateByService import datadog.trace.tracer.writer.SampleRateByService
import datadog.trace.tracer.writer.Writer import datadog.trace.tracer.writer.Writer
import datadog.trace.util.gc.GCUtils
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification import spock.lang.Specification
@ -125,7 +126,7 @@ class TracerTest extends Specification {
span = null span = null
def traceRef = new WeakReference<>(rootSpan.getTrace()) def traceRef = new WeakReference<>(rootSpan.getTrace())
rootSpan = null rootSpan = null
TestUtils.awaitGC(traceRef) GCUtils.awaitGC(traceRef)
then: "invalid trace is written" then: "invalid trace is written"
testWriter.waitForTraces(1) testWriter.waitForTraces(1)
@ -151,7 +152,7 @@ class TracerTest extends Specification {
continuation = null continuation = null
def traceRef = new WeakReference<>(rootSpan.getTrace()) def traceRef = new WeakReference<>(rootSpan.getTrace())
rootSpan = null rootSpan = null
TestUtils.awaitGC(traceRef) GCUtils.awaitGC(traceRef)
then: "invalid trace is written" then: "invalid trace is written"
testWriter.waitForTraces(1) testWriter.waitForTraces(1)

View File

@ -16,6 +16,7 @@ include ':dd-java-agent:agent-jmxfetch'
// misc // misc
include ':dd-java-agent:testing' include ':dd-java-agent:testing'
include ':utils:gc-utils'
// smoke tests // smoke tests
include ':dd-smoke-tests:play' include ':dd-smoke-tests:play'

View File

@ -0,0 +1 @@
apply from: "${rootDir}/gradle/java.gradle"

View File

@ -1,9 +1,8 @@
package datadog.trace.tracer; package datadog.trace.util.gc;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
// TODO: stop copy-pasting this! public abstract class GCUtils {
public class TestUtils {
public static void awaitGC() { public static void awaitGC() {
Object obj = new Object(); Object obj = new Object();