-
Notifications
You must be signed in to change notification settings - Fork 881
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Run tests with javaagent. #1643
Conversation
javaagent-spi/src/main/java/io/opentelemetry/javaagent/spi/exporter/SpanExporterFactory.java
Outdated
Show resolved
Hide resolved
...mmon/src/main/java/io/opentelemetry/javaagent/testing/common/AgentTestingExporterAccess.java
Show resolved
Hide resolved
...mmon/src/main/java/io/opentelemetry/javaagent/testing/common/AgentTestingExporterAccess.java
Show resolved
Hide resolved
...rter/src/main/java/io/opentelemetry/javaagent/testing/exporter/OtlpInMemorySpanExporter.java
Outdated
Show resolved
Hide resolved
@@ -0,0 +1,80 @@ | |||
plugins { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This project is essentially a "custom distro", with no instrumentation included, and the testing exporter included.
.../agent-for-testing/src/test/java/io/opentelemetry/javaagent/testing/AgentForTestingTest.java
Show resolved
Hide resolved
Disclaimer: I haven't read code changes yet, only PR description :) First: why don't we want to use the full agent for tests? Not module specific, but full-blown agent as it would run in production? Second: maybe it is easier to cross JVM boundaries and void classloading issues completely? Use fake-backend as in smoke-tests and adapt our assertions to OTLP? |
I think this will have significant penalty on build time for a single instrumentation, especially when developing. It means when working on one module, you have to build the entire repo / agent just to run its tests.
Yeah the thought of adapting assertions to OTLP came to mind. I think we can think about it in followup, I'm concerned it may have some drawbacks like coverage (found one field in SpanData not in OTLP) and inability to use helpers that we may make in the SDK (like the After reading the code, you'll see we're effectively doing the same as the |
On my machine after clean |
Is that with everything coming from local build cache? That's much faster than most builds I've seen :O |
...ing-common/src/main/java/io/opentelemetry/javaagent/testing/common/AgentInstallerAccess.java
Outdated
Show resolved
Hide resolved
.../agent-for-testing/src/test/java/io/opentelemetry/javaagent/testing/AgentForTestingTest.java
Show resolved
Hide resolved
…-instrumentation into run-tests-with-agent
...t-exporter/src/main/java/io/opentelemetry/javaagent/testing/bytebuddy/TestAgentListener.java
Show resolved
Hide resolved
...src/main/java/io/opentelemetry/javaagent/testing/bytebuddy/TestByteBuddyAgentCustomizer.java
Show resolved
Hide resolved
testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/AgentTestRunner.java
Outdated
Show resolved
Hide resolved
testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/AgentTestRunner.java
Show resolved
Hide resolved
Good progress - I think most features are implemented (though not fully verified for corner cases such as "skip transformation" and "global ignores mather" checking), my scariest point was LOTS of cleanup left so no need for a detailed review yet ( |
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java
Outdated
Show resolved
Hide resolved
…-instrumentation into run-tests-with-agent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My yak clippers are getting a huge workout. Got many tests passing now, still a few stubborns one. Particularly tough ones are
-
Don't know what to do about opentelemetry-api-beta tests since they very much depend on not working with a shaded agent.
-
JAX tests that use
runUnderServerTrace
(and I think other similar tests) fail confusingly - the trace assertions all assert the span is the request span like "/a", but I always see it fail with it being something like "test", which seems correct to me because of the use ofrunUnderTrace
. Haven't been able to figure out yet what I'm missing that causes these assertions to pass before this PR.
// OpenTelemetry SDK is not needed for compilation, and :opentelemetry-sdk-shaded-for-testing | ||
// is brought in for tests by project(:testing-common) below | ||
exclude group: 'io.opentelemetry', module: 'opentelemetry-sdk' | ||
} | ||
implementation deps.bytebuddy | ||
annotationProcessor deps.autoservice | ||
implementation deps.autoservice | ||
compileOnly deps.autoservice |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seemingly innocent change caused a lot of breakage since guava, previously set by autoservice, ended up getting too new for many of our projects. But it's probably better to have the manual downgrading as now to know about these instead of the luck.
|
||
// The sources are packaged into the testing jar so we need to make sure to exclude from the test | ||
// classpath, which automatically inherits them, to ensure our shaded versions are used. | ||
classpath = classpath.filter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized my previous testing wasn't actually doing what we wanted - the non-shaded classes from the test classpath would still be used from the agent. Now it's always the shaded ones.
...opentelemetry/javaagent/instrumentation/awssdk/v2_2/ExecutionInterceptorInstrumentation.java
Outdated
Show resolved
Hide resolved
testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/InMemoryExporter.java
Outdated
Show resolved
Hide resolved
@trask Thanks for the hint - removed the dependencies onto agent classes from testing-common and updated most tests to not access them. There are some hairy ones left, and still not too sure about opentelemetry-api-beta (maybe I need to move the tests to a different project that doesn't use the |
@iNikem tests are failing:
|
Ignore me (again), I remember there was special packaging of this class, need to carry that over to the new stuff. |
@iNikem one other thing, github actions log file kept stopping on me mid-way through the build, which made it hard to troubleshoot, removing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think we lack documentation about new testing infrastructure. The one that would help. e.g. me, to understand how do tests work and how should I go around fixing bugs in test infra. E.g. what are these new modules agent-for-testing
and agent-exporter
? What are those XXXAccess
classes and why they are written the way they are?
|| name.startsWith("org.apache.lucene.") | ||
|| name.startsWith("org.apache.tartarus.") | ||
|| name.startsWith("org.json.simple.") | ||
|| name.startsWith("org.yaml.snakeyaml.")) { | ||
return true; | ||
} | ||
|
||
if (name.startsWith("net.sf.cglib.")) { | ||
return !name.equals("net.sf.cglib.core.internal.LoadingCache$2"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still see it :)
bug? what bugs? 😂 good suggestion, added 👍 |
requested changes are complete and reviewer is on vacation
Don't get too excited, just first steps in this change for now :)
I wanted to get it out as a PoC just to see what you think of the general direction. Running a test with the agent active, having it load instrumentation for the project under test, and asserting on exported spans works. I'm hoping other steps aren't extremely hard but there are still a few big steps left and a chance of hitting a roadblock, but hope not.
I think there are these major components left
Allow registering multiple custom instrumentation like some of our tests require.
I am using the
otel.initializer_jar
mechanism to load instrumentation. Some thoughts on how to proceedotel.initializer_jar
to accept a CSV of jars.otel.initializer_jar
and generate an agent JAR for each project with everything bundled. Slows down build more (even more repackaging)First option seems ok I guess? But maybe doesn't fit with our general customization plans. Second option doesn't seem that bad, especially if
java-concurrent
andjava-classloader
are packaged into the agent (always used), making the dual-packaging rare.Allow registering transformation listeners
If I understand classloaders correctly, we can't simply pass a
AgentBuilder.Listener
from the test classloader to the agent classloader since the implementation would not be inheriting from the agent classloader's class (@trask correct me if I'm wrong, if so things are trivial). It would be very easy to define an interface similar toAgentBuilder.Listener
in the bootstrap classloader for our use. Unfortunately,TRANSFORMED_CLASSES_TYPES
depends on byte buddy'sTypeDescription
which puts a wrinkle in this. But instead of a mostly similar, mostly generic Listener, we could have the callback just accept aboolean matchedGlobalLibrariesIgnoreMatcher
, which is only useful for our test, but guess it's ok.Edit: Added
TransformationListener
as a POC for this.Allowing updates to
Config
This seems relatively easy, instead of modifyingINSTANCE
directly by initializingConfig
in the test classloader, we can just provide a private (accessed-through-reflection) method that acceptsProperties
and creates theConfig
in the agent classloader.Config's in bootstrap classloader :DBut it's shadedAlso feel free to bring up any potential other gotchas you see to come up with strategies to squash them :D