Skip to content

Commit

Permalink
add test
Browse files Browse the repository at this point in the history
  • Loading branch information
laurit committed Jun 16, 2022
1 parent e85eb8c commit a88e04f
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import io.opentelemetry.api.trace.SpanKind
import io.opentelemetry.instrumentation.jdbc.TestConnection
import io.opentelemetry.instrumentation.jdbc.TestDriver
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
import io.opentelemetry.javaagent.instrumentation.jdbc.test.ProxyStatementFactory
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import org.apache.derby.jdbc.EmbeddedDataSource
import org.apache.derby.jdbc.EmbeddedDriver
Expand Down Expand Up @@ -820,4 +821,36 @@ class JdbcInstrumentationTest extends AgentInstrumentationSpecification {
return super.getMetaData()
}
}

// regression test for https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/6015
def "test proxy statement"() {
def connection = new Driver().connect(jdbcUrls.get("h2"), null)
Statement statement = connection.createStatement()
Statement proxyStatement = ProxyStatementFactory.proxyStatement(statement)
ResultSet resultSet = runWithSpan("parent") {
return proxyStatement.executeQuery("SELECT 3")
}

expect:
resultSet.next()
resultSet.getInt(1) == 3
assertTraces(1) {
trace(0, 2) {
span(0) {
name "parent"
kind SpanKind.INTERNAL
hasNoParent()
}
span(1) {
name "SELECT $dbNameLower"
kind CLIENT
childOf span(0)
}
}
}

cleanup:
statement.close()
connection.close()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.jdbc.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.sql.Statement;

public class ProxyStatementFactory {

public static Statement proxyStatement(Statement statement) throws Exception {
TestClassLoader classLoader = new TestClassLoader(ProxyStatementFactory.class.getClassLoader());
Class<?> testInterface = classLoader.loadClass(TestInterface.class.getName());
if (testInterface.getClassLoader() != classLoader) {
throw new IllegalStateException("wrong class loader");
}
InvocationHandler invocationHandler = (proxy, method, args) -> method.invoke(statement, args);
Statement proxyStatement =
(Statement)
Proxy.newProxyInstance(
classLoader, new Class<?>[] {Statement.class, testInterface}, invocationHandler);
// adding package private interface TestInterface to jdk proxy forces defining the proxy class
// in the same package as the package private interface
if (!proxyStatement
.getClass()
.getName()
.startsWith("io.opentelemetry.javaagent.instrumentation.jdbc.test")) {
throw new IllegalStateException("proxy statement is in wrong package");
}

return proxyStatement;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.jdbc.test;

import java.net.URL;
import java.net.URLClassLoader;

public class TestClassLoader extends URLClassLoader {

public TestClassLoader(ClassLoader parent) {
super(
new URL[] {TestClassLoader.class.getProtectionDomain().getCodeSource().getLocation()},
parent);
}

@Override
protected synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
Class<?> clazz = findLoadedClass(name);
if (clazz != null) {
return clazz;
}
if (name.startsWith("io.opentelemetry.javaagent.instrumentation.jdbc.test")) {
try {
return findClass(name);
} catch (ClassNotFoundException exception) {
// ignore
}
}
return super.loadClass(name, resolve);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.jdbc.test;

// Adding a package private interface to jdk proxy forces defining the proxy class in the package
// of the package private class. Usually proxy classes are defined in a package that we exclude from
// instrumentation. We use this class to force proxy into a different package so it would get
// instrumented.
interface TestInterface {}

0 comments on commit a88e04f

Please sign in to comment.