From 1176029765b627990715df611ec99b72d859644b Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Tue, 21 Dec 2021 13:10:44 +0900 Subject: [PATCH] Migrate ShadowPackageRenamingTest to Java to avoid spock workaround (#4960) --- javaagent/build.gradle.kts | 3 +- .../ShadowPackageRenamingTest.groovy | 122 ------------------ .../ShadowPackageRenamingTest.java | 119 +++++++++++++++++ 3 files changed, 120 insertions(+), 124 deletions(-) delete mode 100644 javaagent/src/test/groovy/io/opentelemetry/javaagent/classloading/ShadowPackageRenamingTest.groovy create mode 100644 javaagent/src/test/java/io/opentelemetry/javaagent/classloading/ShadowPackageRenamingTest.java diff --git a/javaagent/build.gradle.kts b/javaagent/build.gradle.kts index fbdd8b7757..0fe2f8c535 100644 --- a/javaagent/build.gradle.kts +++ b/javaagent/build.gradle.kts @@ -95,9 +95,8 @@ dependencies { testImplementation("com.google.guava:guava") testImplementation("io.opentelemetry:opentelemetry-sdk") - // TODO(anuraaga): Remove after github.com/open-telemetry/opentelemetry-java/issues/3999 - testImplementation("io.opentelemetry:opentelemetry-sdk-metrics") testImplementation("io.opentracing.contrib.dropwizard:dropwizard-opentracing:0.2.2") + testImplementation("org.assertj:assertj-core") } val javaagentDependencies = dependencies diff --git a/javaagent/src/test/groovy/io/opentelemetry/javaagent/classloading/ShadowPackageRenamingTest.groovy b/javaagent/src/test/groovy/io/opentelemetry/javaagent/classloading/ShadowPackageRenamingTest.groovy deleted file mode 100644 index efdce5853f..0000000000 --- a/javaagent/src/test/groovy/io/opentelemetry/javaagent/classloading/ShadowPackageRenamingTest.groovy +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.classloading - -import com.google.common.reflect.ClassPath -import io.opentelemetry.javaagent.IntegrationTestUtils -import io.opentelemetry.sdk.OpenTelemetrySdk -import spock.lang.Specification - -class ShadowPackageRenamingTest extends Specification { - - - static final String[] AGENT_PACKAGE_PREFIXES = [ - "io.opentelemetry.instrumentation.api", - // jackson - "com.fasterxml.jackson", - // bytebuddy - "net.bytebuddy", - "org.yaml.snakeyaml", - // disruptor - "com.lmax.disruptor", - // okHttp - "okhttp3", - "okio", - "jnr", - "org.objectweb.asm", - "com.kenai", - // Custom RxJava Utility - "rx.__OpenTelemetryTracingUtil" - ] - - def "agent dependencies renamed"() { - setup: - Class clazz = - IntegrationTestUtils.getAgentClassLoader() - .loadClass("io.opentelemetry.javaagent.tooling.AgentInstaller") - URL userSdk = - OpenTelemetrySdk.getProtectionDomain().getCodeSource().getLocation() - URL agentSdkDep = - clazz - .getClassLoader() - .loadClass("io.opentelemetry.sdk.OpenTelemetrySdk") - .getProtectionDomain() - .getCodeSource() - .getLocation() - URL agentSource = - clazz.getProtectionDomain().getCodeSource().getLocation() - - expect: - agentSource.getFile().endsWith(".jar") - agentSource.getProtocol() == "file" - agentSource == agentSdkDep - agentSource.getFile() != userSdk.getFile() - } - - def "agent classes not visible"() { - when: - ClassLoader.getSystemClassLoader().loadClass("io.opentelemetry.javaagent.tooling.AgentInstaller") - then: - thrown ClassNotFoundException - } - - def "agent jar contains no bootstrap classes"() { - setup: - ClassPath agentClasspath = ClassPath.from(IntegrationTestUtils.getAgentClassLoader()) - - ClassPath bootstrapClasspath = ClassPath.from(IntegrationTestUtils.getBootstrapProxy()) - Set bootstrapClasses = new HashSet<>() - List bootstrapPrefixes = IntegrationTestUtils.getBootstrapPackagePrefixes() - List badBootstrapPrefixes = [] - for (ClassPath.ClassInfo info : bootstrapClasspath.getAllClasses()) { - bootstrapClasses.add(info.getName()) - // make sure all bootstrap classes can be loaded from system - ClassLoader.getSystemClassLoader().loadClass(info.getName()) - boolean goodPrefix = false - for (int i = 0; i < bootstrapPrefixes.size(); ++i) { - if (info.getName().startsWith(bootstrapPrefixes[i])) { - goodPrefix = true - break - } - } - if (info.getName() == 'io.opentelemetry.javaagent.OpenTelemetryAgent') { - // io.opentelemetry.javaagent.OpenTelemetryAgent isn't needed in the bootstrap prefixes - // because it doesn't live in the bootstrap class loader, but it's still "good" for the - // purpose of this test which is just checking all the classes sitting directly inside of - // the agent jar - goodPrefix = true - } - if (!goodPrefix) { - badBootstrapPrefixes.add(info.getName()) - } - } - - List agentDuplicateClassFile = new ArrayList<>() - List badAgentPrefixes = [] - // TODO (trask) agentClasspath.getAllClasses() is empty - // so this part of the test doesn't verify what it thinks it is verifying - for (ClassPath.ClassInfo classInfo : agentClasspath.getAllClasses()) { - if (bootstrapClasses.contains(classInfo.getName())) { - agentDuplicateClassFile.add(classInfo) - } - boolean goodPrefix = false - for (int i = 0; i < AGENT_PACKAGE_PREFIXES.length; ++i) { - if (classInfo.getName().startsWith(AGENT_PACKAGE_PREFIXES[i])) { - goodPrefix = true - break - } - } - if (!goodPrefix) { - badAgentPrefixes.add(classInfo.getName()) - } - } - - expect: - agentDuplicateClassFile == [] - badBootstrapPrefixes == [] - badAgentPrefixes == [] - } -} diff --git a/javaagent/src/test/java/io/opentelemetry/javaagent/classloading/ShadowPackageRenamingTest.java b/javaagent/src/test/java/io/opentelemetry/javaagent/classloading/ShadowPackageRenamingTest.java new file mode 100644 index 0000000000..226d0495af --- /dev/null +++ b/javaagent/src/test/java/io/opentelemetry/javaagent/classloading/ShadowPackageRenamingTest.java @@ -0,0 +1,119 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.classloading; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.google.common.reflect.ClassPath; +import io.opentelemetry.javaagent.IntegrationTestUtils; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.Test; + +public class ShadowPackageRenamingTest { + + private static final List AGENT_PACKAGE_PREFIXES = + Arrays.asList( + "io.opentelemetry.instrumentation.api", + // jackson + "com.fasterxml.jackson", + // bytebuddy + "net.bytebuddy", + "org.yaml.snakeyaml", + // disruptor + "com.lmax.disruptor", + // okHttp + "okhttp3", + "okio", + "jnr", + "org.objectweb.asm", + "com.kenai", + // Custom RxJava Utility + "rx.__OpenTelemetryTracingUtil"); + + @Test + void agentDependenciesRenamed() throws Exception { + Class clazz = + IntegrationTestUtils.getAgentClassLoader() + .loadClass("io.opentelemetry.javaagent.tooling.AgentInstaller"); + URL userSdk = OpenTelemetrySdk.class.getProtectionDomain().getCodeSource().getLocation(); + URL agentSdkDep = + clazz + .getClassLoader() + .loadClass("io.opentelemetry.sdk.OpenTelemetrySdk") + .getProtectionDomain() + .getCodeSource() + .getLocation(); + URL agentSource = clazz.getProtectionDomain().getCodeSource().getLocation(); + + assertThat(agentSource.getFile()).endsWith(".jar"); + assertThat(agentSource.getProtocol()).isEqualTo("file"); + assertThat(agentSource).isEqualTo(agentSdkDep); + assertThat(agentSource.getFile()).isNotEqualTo(userSdk.getFile()); + } + + @Test + void agentClassesNotVisible() { + assertThatThrownBy( + () -> + ClassLoader.getSystemClassLoader() + .loadClass("io.opentelemetry.javaagent.tooling.AgentInstaller")) + .isInstanceOf(ClassNotFoundException.class); + } + + @Test + void agentJarContainsNoBootstrapClasses() throws Exception { + ClassPath agentClasspath = ClassPath.from(IntegrationTestUtils.getAgentClassLoader()); + + ClassPath bootstrapClasspath = ClassPath.from(IntegrationTestUtils.getBootstrapProxy()); + Set bootstrapClasses = new HashSet<>(); + List bootstrapPrefixes = IntegrationTestUtils.getBootstrapPackagePrefixes(); + List badBootstrapPrefixes = new ArrayList<>(); + for (ClassPath.ClassInfo info : bootstrapClasspath.getAllClasses()) { + bootstrapClasses.add(info.getName()); + // make sure all bootstrap classes can be loaded from system + ClassLoader.getSystemClassLoader().loadClass(info.getName()); + boolean goodPrefix = + bootstrapPrefixes.stream().anyMatch(prefix -> info.getName().startsWith(prefix)); + if (info.getName().equals("io.opentelemetry.javaagent.OpenTelemetryAgent")) { + // io.opentelemetry.javaagent.OpenTelemetryAgent isn't needed in the bootstrap prefixes + // because it doesn't live in the bootstrap class loader, but it's still "good" for the + // purpose of this test which is just checking all the classes sitting directly inside of + // the agent jar + goodPrefix = true; + } + if (!goodPrefix) { + badBootstrapPrefixes.add(info.getName()); + } + } + + List agentDuplicateClassFile = new ArrayList<>(); + List badAgentPrefixes = new ArrayList<>(); + // TODO (trask) agentClasspath.getAllClasses() is empty + // so this part of the test doesn't verify what it thinks it is verifying + for (ClassPath.ClassInfo classInfo : agentClasspath.getAllClasses()) { + if (bootstrapClasses.contains(classInfo.getName())) { + agentDuplicateClassFile.add(classInfo); + } + boolean goodPrefix = + AGENT_PACKAGE_PREFIXES.stream() + .anyMatch(prefix -> classInfo.getName().startsWith(prefix)); + if (!goodPrefix) { + badAgentPrefixes.add(classInfo.getName()); + } + } + + assertThat(agentDuplicateClassFile).isEmpty(); + assertThat(badBootstrapPrefixes).isEmpty(); + assertThat(badAgentPrefixes).isEmpty(); + } +}