DataDog / dd-trace-java

Datadog APM client for Java
https://docs.datadoghq.com/tracing/languages/java
Apache License 2.0
572 stars 284 forks source link

"Could not create service of type CiVisibilityGradleListener." when running plugin tests with ProjectBuilder.build #7596

Closed staktrace closed 2 weeks ago

staktrace commented 2 weeks ago

Same datadog setup as in https://github.com/DataDog/dd-trace-java/issues/7521, but using dd-java-agent version 1.39.0. We have a gradle module that creates a gradle plugin. The test for the plugin looks like this:

package mypackage

import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.gradle.api.GradleException
import org.gradle.testfixtures.ProjectBuilder
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource

internal class PluginTest {
  private val project = ProjectBuilder.builder().build()

  @BeforeEach
  fun setUp() {
    project.pluginManager.run {
      apply(OurCustomPlugin::class.java)
    }
  }

  .. // @Test functions here

when this test is run with the datadog agent, we get an exception stack like this:

...

Caused by: org.gradle.internal.service.ServiceCreationException: Could not create service of type CiVisibilityGradleListener.
...
Caused by: java.lang.UnsupportedOperationException: (No message provided)
at org.gradle.testfixtures.internal.ProjectBuilderImpl$TestRootBuild.getStartParameter(ProjectBuilderImpl.java:303) 
at datadog.trace.instrumentation.gradle.CiVisibilityGradleListener.getStartParameter(CiVisibilityGradleListener.java:115)   
at datadog.trace.instrumentation.gradle.CiVisibilityGradleListener.<init>(CiVisibilityGradleListener.java:105)  
at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)   
at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)    
at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)    
at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)    
at java.lang.reflect.Constructor.newInstance(Constructor.java:480)  
at org.gradle.internal.service.DefaultServiceRegistry$ConstructorService.invokeMethod(DefaultServiceRegistry.java:1158) 
at org.gradle.internal.service.DefaultServiceRegistry$FactoryService.createServiceInstance(DefaultServiceRegistry.java:959)

I guess that the DD agent code is calling getStartParameter() on the project object but the project object is coming from the gradle testFixtures and doesn't have a start paramater? I'm not really sure.

If this information is insufficient to reproduce the problem I can try to make a sanitized standalone reproducer - please let me know!

nikita-tkachenko-datadog commented 2 weeks ago

Hi @staktrace, thank you for reporting this!

The error occurs because in your plugin tests you're initiating a Gradle build, and the tracer tries to instrument this build as if it was a regular Gradle invocation. Normally this type of "build-inside-a-build" situation is handled by the tracer automatically, but since your setup is somewhat non-standard (as far as I recall you're injecting the tracer into the test tasks by hand) additional steps are required. Could you please try adding the following property to your test tasks' JVM args and let me know if that helps? -Ddd.civisibility.build.instrumentation.enabled=false

Thanks!

staktrace commented 2 weeks ago

Setting that property does get the tests passing, yes. Is this something that's safe to apply on all test tasks in our shared build-logic code? Or should it generally be restricted to gradle plugin modules?

nikita-tkachenko-datadog commented 2 weeks ago

This is safe to apply everywhere. All it does is disable Gradle/Maven instrumentation, which you don't need given that you're already tracing the JVMs that execute tests.

staktrace commented 2 weeks ago

Great, thank you! In that case feel free to close out this issue. 🙇