Run tests with javaagent. (#1643)
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
parent
5b2e4ce1c7
commit
8d74baa2e4
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
while true
|
||||
do
|
||||
sleep 60
|
||||
file="/tmp/deadlock-detector-$(date +"%Y-%m-%d-%H-%M-%S").txt"
|
||||
for pid in $(jps | grep -v Jps | awk '{ print $1 }')
|
||||
do
|
||||
jcmd $pid VM.command_line >> $file
|
||||
jcmd $pid Thread.print >> $file
|
||||
if jcmd $pid Thread.print | grep -q SimpleLogger
|
||||
then
|
||||
# check once more to eliminate most of the sporadic finds
|
||||
if jcmd $pid Thread.print | grep -q SimpleLogger
|
||||
then
|
||||
jcmd $pid GC.heap_dump /tmp/deadlock-detector-$pid.hprof
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done &
|
|
@ -18,12 +18,19 @@ jobs:
|
|||
with:
|
||||
job-id: jdk11
|
||||
|
||||
- name: Start deadlock detector
|
||||
run: .github/scripts/deadlock-detector.sh
|
||||
|
||||
- name: Build
|
||||
uses: nick-invision/retry@v2.2.0
|
||||
run: ./gradlew check --stacktrace -x :smoke-tests:test
|
||||
|
||||
- name: Upload deadlock detector artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
command: ./gradlew check --stacktrace -x :smoke-tests:test
|
||||
timeout_minutes: 90
|
||||
max_attempts: 3
|
||||
name: deadlock-detector-build
|
||||
path: /tmp/deadlock-detector-*
|
||||
if-no-files-found: ignore
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -49,12 +56,19 @@ jobs:
|
|||
with:
|
||||
job-id: jdk${{ matrix.java }}
|
||||
|
||||
- name: Start deadlock detector
|
||||
run: .github/scripts/deadlock-detector.sh
|
||||
|
||||
- name: Test
|
||||
uses: nick-invision/retry@v2.2.0
|
||||
run: ./gradlew test -PtestJavaVersion=${{ matrix.java }} --stacktrace -x :smoke-tests:test -Porg.gradle.java.installations.paths=${{ steps.setup-test-java.outputs.path }} -Porg.gradle.java.installations.auto-download=false
|
||||
|
||||
- name: Upload deadlock detector artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
command: ./gradlew test -PtestJavaVersion=${{ matrix.java }} --stacktrace -x :smoke-tests:test -Porg.gradle.java.installations.paths=${{ steps.setup-test-java.outputs.path }} -Porg.gradle.java.installations.auto-download=false
|
||||
timeout_minutes: 90
|
||||
max_attempts: 3
|
||||
name: deadlock-detector-test-${{ matrix.java }}
|
||||
path: /tmp/deadlock-detector-*
|
||||
if-no-files-found: ignore
|
||||
|
||||
smoke-test:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -72,11 +86,7 @@ jobs:
|
|||
job-id: smokeTests
|
||||
|
||||
- name: Test
|
||||
uses: nick-invision/retry@v2.2.0
|
||||
with:
|
||||
command: ./gradlew :smoke-tests:test
|
||||
timeout_minutes: 90
|
||||
max_attempts: 3
|
||||
run: ./gradlew :smoke-tests:test
|
||||
|
||||
setup-muzzle-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
@ -54,6 +54,10 @@ See [Writing instrumentation](docs/contributing/writing-instrumentation.md)
|
|||
|
||||
See [Understanding the javaagent components](docs/contributing/javaagent-jar-components.md)
|
||||
|
||||
### Understanding the javaagent instrumentation testing components
|
||||
|
||||
See [Understanding the javaagent instrumentation testing components](docs/contributing/javaagent-test-infra.md)
|
||||
|
||||
### Debugging
|
||||
|
||||
See [Debugging](docs/contributing/debugging.md)
|
||||
|
|
|
@ -21,10 +21,6 @@ gradlePlugin {
|
|||
id = "muzzle"
|
||||
implementationClass = "MuzzlePlugin"
|
||||
}
|
||||
create("javaagent-instrumentation-plugin") {
|
||||
id = "io.opentelemetry.javaagent.instrumentation-instrumentation"
|
||||
implementationClass = "io.opentelemetry.instrumentation.gradle.AutoInstrumentationPlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.gradle;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.plugins.JavaLibraryPlugin;
|
||||
import org.gradle.api.tasks.Internal;
|
||||
import org.gradle.api.tasks.testing.Test;
|
||||
import org.gradle.process.CommandLineArgumentProvider;
|
||||
|
||||
/**
|
||||
* {@link Plugin} to initialize projects that implement auto instrumentation using bytecode
|
||||
* manipulation. Currently builds the special bootstrap classpath that is needed by bytecode tests.
|
||||
*/
|
||||
// TODO(anuraaga): Migrate more build logic into this plugin to avoid having two places for it.
|
||||
public class AutoInstrumentationPlugin implements Plugin<Project> {
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
project.getPlugins().apply(JavaLibraryPlugin.class);
|
||||
project
|
||||
.getTasks()
|
||||
.withType(
|
||||
Test.class,
|
||||
task -> {
|
||||
task.dependsOn(":testing-bootstrap:shadowJar");
|
||||
File testingBootstrapJar =
|
||||
new File(
|
||||
project.project(":testing-bootstrap").getBuildDir(),
|
||||
"libs/testing-bootstrap.jar");
|
||||
// Make sure tests get rerun if the contents of the testing-bootstrap.jar change
|
||||
task.getInputs().property("testing-bootstrap-jar", testingBootstrapJar);
|
||||
task.getJvmArgumentProviders().add(new InstrumentationTestArgs(testingBootstrapJar));
|
||||
});
|
||||
}
|
||||
|
||||
private static class InstrumentationTestArgs implements CommandLineArgumentProvider {
|
||||
private final File bootstrapJar;
|
||||
|
||||
@Internal
|
||||
public File getBootstrapJar() {
|
||||
return bootstrapJar;
|
||||
}
|
||||
|
||||
public InstrumentationTestArgs(File bootstrapJar) {
|
||||
this.bootstrapJar = bootstrapJar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> asArguments() {
|
||||
return Arrays.asList(
|
||||
"-Xbootclasspath/a:" + bootstrapJar.getAbsolutePath(), "-Dnet.bytebuddy.raw=true");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
### Understanding the javaagent components
|
||||
|
||||
OpenTelemetry Auto Instrumentation java agent's jar can logically be divided
|
||||
into 3 parts:
|
||||
The javaagent jar can logically be divided into 3 parts:
|
||||
|
||||
* Modules that live in the system class loader
|
||||
* Modules that live in the bootstrap class loader
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
### Understanding the javaagent instrumentation testing components
|
||||
|
||||
Javaagent instrumentation tests are run using a fully shaded `-javaagent` in order to perform
|
||||
the same bytecode instrumentation as when the agent is run against a normal app.
|
||||
|
||||
There are a few key components that make this possible, described below.
|
||||
|
||||
### gradle/instrumentation.gradle
|
||||
|
||||
* shades the instrumentation
|
||||
* adds jvm args to the test configuration
|
||||
* -javaagent:[agent for testing]
|
||||
* -Dotel.initializer.jar=[shaded instrumentation jar]
|
||||
|
||||
The `otel.initializer.jar` property is used to load the shaded instrumentation jar into the
|
||||
`AgentClassLoader`, so that the javaagent jar doesn't need to be re-built each time.
|
||||
|
||||
### :testing:agent-exporter
|
||||
|
||||
This contains the span and metric exporters that are used.
|
||||
|
||||
These are in-memory exporters, so that the tests can verify the spans and metrics being exported.
|
||||
|
||||
These exporters and the in-memory data live in the `AgentClassLoader`, so tests must access them
|
||||
using reflection. To simplify this, they store the in-memory data using the OTLP protobuf objects,
|
||||
so that they can be serialized into byte arrays inside the `AgentClassLoader`, then passed back
|
||||
to the tests and deserialized inside their class loader where they can be verified. The
|
||||
`:testing-common` module (described below) hides this complexity from instrumentation test authors.
|
||||
|
||||
### :agent-for-testing
|
||||
|
||||
This is a custom distro of the javaagent that embeds the `:testing:agent-exporter`.
|
||||
|
||||
### :testing-common
|
||||
|
||||
This module provides methods to help verify the span and metric data produced by the
|
||||
instrumentation, hiding the complexity of accessing the in-memory exporters that live in the
|
||||
`AgentClassLoader`.
|
|
@ -77,12 +77,12 @@ only depend on the OpenTelemetry API, `instrumentation-common`, and the instrume
|
|||
[instrumentation-library.gradle](../../gradle/instrumentation-library.gradle) needs to be applied to
|
||||
configure build tooling for the library.
|
||||
|
||||
## Writing unit tests
|
||||
## Writing instrumentation tests
|
||||
|
||||
Once the instrumentation is completed, we add unit tests to the `testing` module. Tests will
|
||||
Once the instrumentation is completed, we add tests to the `testing` module. Tests will
|
||||
generally apply to both library and agent instrumentation, with the only difference being how a client
|
||||
or server is initialized. In a library test, there will be code calling into the instrumentation API,
|
||||
while in an agent test, it will generally just use the underlying library's API as is. Create unit tests in an
|
||||
while in an agent test, it will generally just use the underlying library's API as is. Create tests in an
|
||||
abstract class with an abstract method that returns an instrumented object like a client. The class
|
||||
should itself extend from `InstrumentationSpecification` to be recognized by Spock and include helper
|
||||
methods for assertions.
|
||||
|
@ -100,11 +100,11 @@ Now that we have working instrumentation, we can implement agent instrumentation
|
|||
do not have to modify their apps to use it. Make sure the `javaagent` submodule has a dependency on the
|
||||
`library` submodule and a test dependency on the `testing` submodule. Agent instrumentation defines
|
||||
classes to match against to generate bytecode for. You will often match against the class you used
|
||||
in the unit test for library instrumentation, for example the builder of a client. And then you could
|
||||
in the test for library instrumentation, for example the builder of a client. And then you could
|
||||
match against the method that creates the builder, for example its constructor. Agent instrumentation
|
||||
can inject byte code to be run after the constructor returns, which would invoke e.g.,
|
||||
`registerInterceptor` and initialize the instrumentation. Often, the code inside the byte code
|
||||
decorator will be identical to the one in the unit test you wrote above - the agent does the work for
|
||||
decorator will be identical to the one in the test you wrote above - the agent does the work for
|
||||
initializing the instrumentation library, so a user doesn't have to.
|
||||
|
||||
With that written, let's add tests for the agent instrumentation. We basically want to ensure that
|
||||
|
@ -113,6 +113,34 @@ the base class you wrote earlier, but in this, create a client using none of the
|
|||
only the ones offered by the library. Implement the `AgentTestRunner` trait for common setup logic,
|
||||
and try running. All the tests should pass for agent instrumentation too.
|
||||
|
||||
Note that all the tests inside the `javaagent` module will be run using the shaded `-javaagent`
|
||||
in order to perform the same bytecode instrumentation as when the agent is run against a normal app.
|
||||
This means that the javaagent instrumentation will be inside the javaagent (inside of the
|
||||
`AgentClassLoader`) and will not be directly accessible to your test code. See the next section in
|
||||
case you need to write unit tests that directly access the javaagent instrumentation.
|
||||
|
||||
## Writing Java agent unit tests
|
||||
|
||||
As mentioned above, tests in the `javaagent` module cannot access the javaagent instrumentation
|
||||
classes directly.
|
||||
|
||||
Ideally javaagent instrumentation is just a thin wrapper over library instrumentation, and so there
|
||||
is no need to write unit tests that directly access the javaagent instrumentation classes.
|
||||
|
||||
If you still want to write a unit test against javaagent instrumentation, add another module
|
||||
named `javaagent-unittests`. Continuing with the example above:
|
||||
|
||||
```
|
||||
instrumentation ->
|
||||
...
|
||||
yarpc-1.0 ->
|
||||
javaagent
|
||||
yarpc-1.0-javaagent.gradle
|
||||
javaagent-unittest
|
||||
yarpc-1.0-javaagent-unittest.gradle
|
||||
...
|
||||
```
|
||||
|
||||
### Java agent instrumentation gotchas
|
||||
|
||||
#### Calling Java 8 default methods from advice
|
||||
|
|
|
@ -6,20 +6,15 @@ affecting it negatively, for example introducing crashes.
|
|||
|
||||
## Instrumentation tests
|
||||
|
||||
All instrumentation are written with instrumentation tests - these can be considered
|
||||
the unit tests of this project. Instrumentation tests invoke bytecode manipulation to
|
||||
actually rewrite classes similar to how the agent would in a normal app. By then
|
||||
exercising the instrumented library in a way a user would, for example by issuing
|
||||
requests from an HTTP client, we can assert on the spans that should be generated, including
|
||||
their semantic attributes. A problem in the instrumentation will generally cause
|
||||
spans to be reported incorrectly or not reported at all, and we can find these situations
|
||||
with the instrumentation tests.
|
||||
All instrumentation are written with instrumentation tests - these can be considered the unit tests
|
||||
of this project.
|
||||
|
||||
Note: the instrumentation tests have significant differences from when run against a
|
||||
normal app with `-javaagent`, in particular, our usual shading is not applied which
|
||||
can cause false positives. We have work in progress to actually run tests with `-javaagent`
|
||||
after applying our shading, in which case these tests will run almost identically to
|
||||
a normal app and eliminate false positives. https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/1643
|
||||
Instrumentation tests are run using a fully shaded `-javaagent` in order to perform the same bytecode
|
||||
instrumentation as when the agent is run against a normal app.
|
||||
By then exercising the instrumented library in a way a user would, for example by issuing requests
|
||||
from an HTTP client, we can assert on the spans that should be generated, including their semantic
|
||||
attributes. A problem in the instrumentation will generally cause spans to be reported incorrectly
|
||||
or not reported at all, and we can find these situations with the instrumentation tests.
|
||||
|
||||
## Latest dep tests
|
||||
|
||||
|
|
|
@ -53,4 +53,7 @@ shadowJar {
|
|||
relocate "io.opentelemetry.spi", "io.opentelemetry.javaagent.shaded.io.opentelemetry.spi"
|
||||
relocate "io.opentelemetry.context", "io.opentelemetry.javaagent.shaded.io.opentelemetry.context"
|
||||
|
||||
// relocate OpenTelemetry extensions
|
||||
relocate "io.opentelemetry.extension.kotlin", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.kotlin"
|
||||
relocate "io.opentelemetry.extension.trace.propagation", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.trace.propagation"
|
||||
}
|
|
@ -8,28 +8,28 @@ configurations.all {
|
|||
|
||||
ext {
|
||||
versions = [
|
||||
opentelemetry : '0.13.1',
|
||||
opentelemetryAlpha : "0.13.1-alpha",
|
||||
opentelemetry : '0.13.1',
|
||||
opentelemetryAlpha: "0.13.1-alpha",
|
||||
|
||||
slf4j : "1.7.30",
|
||||
guava : "20.0", // Last version to support Java 7
|
||||
slf4j : "1.7.30",
|
||||
guava : "20.0", // Last version to support Java 7
|
||||
|
||||
spock : "1.3-groovy-$spockGroovyVer",
|
||||
groovy : groovyVer,
|
||||
logback : "1.2.3",
|
||||
bytebuddy : "1.10.18", // Also explicitly specified in buildSrc
|
||||
scala : "2.11.12", // Last version to support Java 7 (2.12+ require Java 8+)
|
||||
kotlin : "1.4.0",
|
||||
coroutines : "1.3.0",
|
||||
springboot : "2.3.1.RELEASE",
|
||||
spock : "1.3-groovy-$spockGroovyVer",
|
||||
groovy : groovyVer,
|
||||
logback : "1.2.3",
|
||||
bytebuddy : "1.10.18", // Also explicitly specified in buildSrc
|
||||
scala : "2.11.12", // Last version to support Java 7 (2.12+ require Java 8+)
|
||||
kotlin : "1.4.0",
|
||||
coroutines : "1.3.0",
|
||||
springboot : "2.3.1.RELEASE",
|
||||
// TODO(anuraaga): Switch off of milestones, this version fixes compatibility with Spock Unroll
|
||||
junit5 : "5.7.0-M1",
|
||||
checkerFramework : "3.6.1",
|
||||
errorprone : "2.4.0",
|
||||
nullaway : "0.8.0",
|
||||
autoValue : "1.7.4",
|
||||
systemLambda : "1.1.0",
|
||||
prometheus : "0.9.0"
|
||||
junit5 : "5.7.0-M1",
|
||||
checkerFramework : "3.6.1",
|
||||
errorprone : "2.4.0",
|
||||
nullaway : "0.8.0",
|
||||
autoValue : "1.7.4",
|
||||
systemLambda : "1.1.0",
|
||||
prometheus : "0.9.0"
|
||||
]
|
||||
|
||||
deps = [
|
||||
|
@ -40,6 +40,7 @@ ext {
|
|||
opentelemetryKotlin : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-extension-kotlin', version: versions.opentelemetry),
|
||||
opentelemetryTraceProps : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-extension-trace-propagators', version: versions.opentelemetry),
|
||||
opentelemetrySdk : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-sdk', version: versions.opentelemetry),
|
||||
opentelemetrySdkMetrics : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-sdk-metrics', version: versions.opentelemetryAlpha),
|
||||
opentelemetryJaeger : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-exporter-jaeger', version: versions.opentelemetry),
|
||||
opentelemetryJaegerThrift : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-exporter-jaeger-thrift', version: versions.opentelemetry),
|
||||
opentelemetryOtlp : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-exporter-otlp', version: versions.opentelemetry),
|
||||
|
@ -49,6 +50,7 @@ ext {
|
|||
opentelemetryLogging : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-exporter-logging', version: versions.opentelemetry),
|
||||
opentelemetryProto : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-proto', version: versions.opentelemetry),
|
||||
opentelemetryResources : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-sdk-extension-resources', version: versions.opentelemetry),
|
||||
opentelemetrySdkTesting : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-sdk-testing', version: versions.opentelemetry),
|
||||
|
||||
// General
|
||||
slf4j : "org.slf4j:slf4j-api:${versions.slf4j}",
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// common gradle file for instrumentation
|
||||
import io.opentelemetry.instrumentation.gradle.bytebuddy.ByteBuddyPluginConfigurator
|
||||
|
||||
apply plugin: 'io.opentelemetry.javaagent.instrumentation-instrumentation'
|
||||
apply plugin: 'net.bytebuddy.byte-buddy'
|
||||
apply plugin: 'muzzle'
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
|
||||
ext {
|
||||
packageInAgentBundle = true
|
||||
|
@ -23,28 +23,24 @@ if (projectDir.name == 'javaagent') {
|
|||
|
||||
afterEvaluate {
|
||||
dependencies {
|
||||
implementation project(':instrumentation-api')
|
||||
implementation project(':javaagent-api')
|
||||
compileOnly project(':instrumentation-api')
|
||||
compileOnly project(':javaagent-api')
|
||||
compileOnly project(':javaagent-bootstrap')
|
||||
// Apply common dependencies for instrumentation.
|
||||
implementation(project(':javaagent-tooling')) {
|
||||
// OpenTelemetry SDK is not needed for compilation, and :opentelemetry-sdk-shaded-for-testing
|
||||
// is brought in for tests by project(:testing-common) below
|
||||
compileOnly(project(':javaagent-tooling')) {
|
||||
// OpenTelemetry SDK is not needed for compilation
|
||||
exclude group: 'io.opentelemetry', module: 'opentelemetry-sdk'
|
||||
}
|
||||
implementation deps.bytebuddy
|
||||
compileOnly deps.bytebuddy
|
||||
annotationProcessor deps.autoservice
|
||||
implementation deps.autoservice
|
||||
implementation deps.slf4j
|
||||
compileOnly deps.autoservice
|
||||
compileOnly deps.slf4j
|
||||
|
||||
// Include instrumentations instrumenting core JDK classes tp ensure interoperability with other instrumentation
|
||||
testImplementation project(':instrumentation:executors:javaagent')
|
||||
// FIXME: we should enable this, but currently this fails tests for google http client
|
||||
//testImplementation project(':instrumentation:http-url-connection:javaagent')
|
||||
testImplementation project(':instrumentation:classloaders:javaagent')
|
||||
testImplementation deps.opentelemetryApi
|
||||
|
||||
testImplementation project(':testing-common')
|
||||
testAnnotationProcessor deps.autoservice
|
||||
testImplementation deps.autoservice
|
||||
testCompileOnly deps.autoservice
|
||||
testImplementation project(':utils:test-utils')
|
||||
|
||||
testImplementation deps.testcontainers
|
||||
|
@ -55,3 +51,63 @@ afterEvaluate {
|
|||
project(':javaagent-tooling').configurations.instrumentationMuzzle + configurations.runtimeClasspath
|
||||
).configure()
|
||||
}
|
||||
|
||||
configurations {
|
||||
testInstrumentation
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
configurations = [project.configurations.runtimeClasspath, project.configurations.testInstrumentation]
|
||||
mergeServiceFiles()
|
||||
|
||||
archiveFileName = 'agent-testing.jar'
|
||||
|
||||
// rewrite library instrumentation dependencies
|
||||
relocate "io.opentelemetry.instrumentation", "io.opentelemetry.javaagent.shaded.instrumentation"
|
||||
|
||||
// Prevents conflict with other SLF4J instances. Important for premain.
|
||||
relocate 'org.slf4j', 'io.opentelemetry.javaagent.slf4j'
|
||||
// rewrite dependencies calling Logger.getLogger
|
||||
relocate 'java.util.logging.Logger', 'io.opentelemetry.javaagent.bootstrap.PatchLogger'
|
||||
|
||||
// prevents conflict with library instrumentation
|
||||
relocate 'io.opentelemetry.instrumentation.api', 'io.opentelemetry.javaagent.shaded.instrumentation.api'
|
||||
|
||||
// relocate OpenTelemetry API usage
|
||||
relocate "io.opentelemetry.api", "io.opentelemetry.javaagent.shaded.io.opentelemetry.api"
|
||||
relocate "io.opentelemetry.spi", "io.opentelemetry.javaagent.shaded.io.opentelemetry.spi"
|
||||
relocate "io.opentelemetry.context", "io.opentelemetry.javaagent.shaded.io.opentelemetry.context"
|
||||
|
||||
// relocate OpenTelemetry extensions
|
||||
relocate "io.opentelemetry.extension.kotlin", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.kotlin"
|
||||
relocate "io.opentelemetry.extension.trace.propagation", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.trace.propagation"
|
||||
|
||||
// this is for instrumentation on opentelemetry-api itself
|
||||
relocate "application.io.opentelemetry", "io.opentelemetry"
|
||||
}
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
jvmArgs "-Dotel.javaagent.debug=true"
|
||||
jvmArgs "-javaagent:${project(":testing:agent-for-testing").buildDir}/libs/javaagent-for-testing.jar"
|
||||
jvmArgs "-Dotel.initializer.jar=${shadowJar.archiveFile.get().asFile.absolutePath}"
|
||||
jvmArgs "-Dinternal.testing.disable.global.library.ignores=true"
|
||||
|
||||
dependsOn shadowJar
|
||||
dependsOn ":testing:agent-for-testing:shadowJar"
|
||||
|
||||
// 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 {
|
||||
if (file("$buildDir/resources/main").equals(it) || file("$buildDir/classes/java/main").equals(it)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
configurations.configureEach {
|
||||
if (it.name.toLowerCase().endsWith('testruntimeclasspath')) {
|
||||
// Added by agent, don't let Gradle bring it in when running tests.
|
||||
exclude module: 'javaagent-bootstrap'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ def applyCodeCoverage = !(
|
|||
project.path == ":javaagent" ||
|
||||
project.path == ":load-generator" ||
|
||||
project.path.startsWith(":benchmark") ||
|
||||
project.path.startsWith(":instrumentation"))
|
||||
project.path.startsWith(":instrumentation") ||
|
||||
project.path.startsWith(":testing-common"))
|
||||
|
||||
if (applyCodeCoverage) {
|
||||
apply from: "$rootDir/gradle/jacoco.gradle"
|
||||
|
|
|
@ -15,4 +15,8 @@ dependencies {
|
|||
|
||||
testImplementation deps.scala
|
||||
testImplementation group: 'com.typesafe.akka', name: 'akka-actor_2.11', version: '2.5.0'
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
jvmArgs '-Dotel.instrumentation.akka-actor.enabled=true'
|
||||
}
|
|
@ -24,10 +24,6 @@ import spock.lang.Shared
|
|||
*/
|
||||
class AkkaExecutorInstrumentationTest extends AgentTestRunner {
|
||||
|
||||
static {
|
||||
System.setProperty("otel.instrumentation.akka-actor.enabled", "true")
|
||||
}
|
||||
|
||||
@Shared
|
||||
def executeRunnable = { e, c -> e.execute((Runnable) c) }
|
||||
@Shared
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
import akka.actor.{Actor, ActorLogging, ActorRef, ActorSystem, Props}
|
||||
import akka.pattern.ask
|
||||
import akka.util.Timeout
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry
|
||||
import io.opentelemetry.api.trace.Tracer
|
||||
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge
|
||||
import io.opentelemetry.javaagent.testing.common.Java8BytecodeBridge
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
// ! == send-message
|
||||
object AkkaActors {
|
||||
val tracer: Tracer =
|
||||
Java8BytecodeBridge.getGlobalTracer("io.opentelemetry.auto")
|
||||
val tracer: Tracer = GlobalOpenTelemetry.getTracer("io.opentelemetry.auto")
|
||||
|
||||
val system: ActorSystem = ActorSystem("helloAkka")
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ dependencies {
|
|||
testLibrary group: 'org.apache.camel', name: 'camel-jaxb-starter', version: '2.20.1'
|
||||
testLibrary group: 'org.apache.camel', name: 'camel-undertow', version: '2.20.1'
|
||||
|
||||
testImplementation project(':instrumentation:apache-httpclient:apache-httpclient-2.0:javaagent')
|
||||
testImplementation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:apache-httpclient:apache-httpclient-2.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
|
||||
testImplementation group: 'org.spockframework', name: 'spock-spring', version: "$versions.spock"
|
||||
|
||||
|
|
|
@ -38,3 +38,7 @@ dependencies {
|
|||
|
||||
testImplementation project(':instrumentation:aws-lambda-1.0:testing')
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
jvmArgs '-Dotel.propagators=tracecontext,xray'
|
||||
}
|
|
@ -9,11 +9,12 @@ import com.amazonaws.services.lambda.runtime.Context
|
|||
import com.amazonaws.services.lambda.runtime.RequestHandler
|
||||
import io.opentelemetry.instrumentation.awslambda.v1_0.AbstractAwsLambdaRequestHandlerTest
|
||||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
||||
import io.opentelemetry.javaagent.testing.common.AgentTestingExporterAccess
|
||||
|
||||
class AwsLambdaTest extends AbstractAwsLambdaRequestHandlerTest implements AgentTestTrait {
|
||||
|
||||
def cleanup() {
|
||||
assert testWriter.forceFlushCalled()
|
||||
assert AgentTestingExporterAccess.forceFlushCalled()
|
||||
}
|
||||
|
||||
static class TestRequestHandler implements RequestHandler<String, String> {
|
||||
|
|
|
@ -8,10 +8,22 @@ package io.opentelemetry.instrumentation.awslambda.v1_0
|
|||
import com.amazonaws.services.lambda.runtime.Context
|
||||
import com.amazonaws.services.lambda.runtime.RequestHandler
|
||||
import com.amazonaws.services.lambda.runtime.events.SQSEvent
|
||||
import io.opentelemetry.api.OpenTelemetry
|
||||
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
|
||||
import io.opentelemetry.context.propagation.ContextPropagators
|
||||
import io.opentelemetry.context.propagation.TextMapPropagator
|
||||
import io.opentelemetry.extension.trace.propagation.AwsXRayPropagator
|
||||
import io.opentelemetry.instrumentation.test.InstrumentationTestTrait
|
||||
|
||||
class AwsLambdaSqsHandlerTest extends AbstractAwsLambdaSqsHandlerTest implements InstrumentationTestTrait {
|
||||
|
||||
// Lambda instrumentation requires XRay propagator to be enabled.
|
||||
static {
|
||||
def propagators = ContextPropagators.create(
|
||||
TextMapPropagator.composite(W3CTraceContextPropagator.instance, AwsXRayPropagator.instance))
|
||||
OpenTelemetry.setGlobalPropagators(propagators)
|
||||
}
|
||||
|
||||
static class TestHandler extends TracingSqsEventHandler {
|
||||
@Override
|
||||
protected void handleEvent(SQSEvent event, Context context) {
|
||||
|
|
|
@ -7,12 +7,24 @@ package io.opentelemetry.instrumentation.awslambda.v1_0
|
|||
|
||||
import com.amazonaws.services.lambda.runtime.Context
|
||||
import com.amazonaws.services.lambda.runtime.RequestHandler
|
||||
import io.opentelemetry.api.OpenTelemetry
|
||||
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
|
||||
import io.opentelemetry.context.propagation.ContextPropagators
|
||||
import io.opentelemetry.context.propagation.TextMapPropagator
|
||||
import io.opentelemetry.extension.trace.propagation.AwsXRayPropagator
|
||||
import io.opentelemetry.instrumentation.test.InstrumentationTestTrait
|
||||
|
||||
class AwsLambdaTest extends AbstractAwsLambdaRequestHandlerTest implements InstrumentationTestTrait {
|
||||
|
||||
// Lambda instrumentation requires XRay propagator to be enabled.
|
||||
static {
|
||||
def propagators = ContextPropagators.create(
|
||||
TextMapPropagator.composite(W3CTraceContextPropagator.instance, AwsXRayPropagator.instance))
|
||||
OpenTelemetry.setGlobalPropagators(propagators)
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
assert testWriter.forceFlushCalled()
|
||||
assert forceFlushCalled()
|
||||
}
|
||||
|
||||
static class TestRequestHandler extends TracingRequestHandler<String, String> {
|
||||
|
|
|
@ -26,7 +26,6 @@ dependencies {
|
|||
|
||||
implementation deps.groovy
|
||||
implementation deps.opentelemetryApi
|
||||
implementation deps.opentelemetryTraceProps
|
||||
implementation deps.spock
|
||||
implementation deps.systemLambda
|
||||
}
|
||||
|
|
|
@ -10,25 +10,11 @@ import static io.opentelemetry.api.trace.Span.Kind.SERVER
|
|||
import com.amazonaws.services.lambda.runtime.Context
|
||||
import com.amazonaws.services.lambda.runtime.RequestHandler
|
||||
import com.github.stefanbirkner.systemlambda.SystemLambda
|
||||
import io.opentelemetry.api.OpenTelemetry
|
||||
import io.opentelemetry.api.trace.attributes.SemanticAttributes
|
||||
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
|
||||
import io.opentelemetry.context.propagation.ContextPropagators
|
||||
import io.opentelemetry.context.propagation.TextMapPropagator
|
||||
import io.opentelemetry.extension.trace.propagation.AwsXRayPropagator
|
||||
import io.opentelemetry.instrumentation.test.InstrumentationSpecification
|
||||
|
||||
abstract class AbstractAwsLambdaRequestHandlerTest extends InstrumentationSpecification {
|
||||
|
||||
// Lambda instrumentation requires XRay propagator to be enabled.
|
||||
static {
|
||||
def propagators = ContextPropagators.create(
|
||||
TextMapPropagator.composite(
|
||||
W3CTraceContextPropagator.instance,
|
||||
AwsXRayPropagator.instance))
|
||||
OpenTelemetry.setGlobalPropagators(propagators)
|
||||
}
|
||||
|
||||
protected static String doHandleRequest(String input, Context context) {
|
||||
if (input == "hello") {
|
||||
return "world"
|
||||
|
|
|
@ -11,25 +11,11 @@ import static io.opentelemetry.api.trace.Span.Kind.SERVER
|
|||
import com.amazonaws.services.lambda.runtime.Context
|
||||
import com.amazonaws.services.lambda.runtime.RequestHandler
|
||||
import com.amazonaws.services.lambda.runtime.events.SQSEvent
|
||||
import io.opentelemetry.api.OpenTelemetry
|
||||
import io.opentelemetry.api.trace.attributes.SemanticAttributes
|
||||
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
|
||||
import io.opentelemetry.context.propagation.ContextPropagators
|
||||
import io.opentelemetry.context.propagation.TextMapPropagator
|
||||
import io.opentelemetry.extension.trace.propagation.AwsXRayPropagator
|
||||
import io.opentelemetry.instrumentation.test.InstrumentationSpecification
|
||||
|
||||
abstract class AbstractAwsLambdaSqsHandlerTest extends InstrumentationSpecification {
|
||||
|
||||
// Lambda instrumentation requires XRay propagator to be enabled.
|
||||
static {
|
||||
def propagators = ContextPropagators.create(
|
||||
TextMapPropagator.composite(
|
||||
W3CTraceContextPropagator.instance,
|
||||
AwsXRayPropagator.instance))
|
||||
OpenTelemetry.setGlobalPropagators(propagators)
|
||||
}
|
||||
|
||||
private static final String AWS_TRACE_HEADER = "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"
|
||||
|
||||
abstract RequestHandler<SQSEvent, Void> handler()
|
||||
|
|
|
@ -48,7 +48,7 @@ dependencies {
|
|||
library group: 'com.amazonaws', name: 'aws-java-sdk-core', version: '1.11.0'
|
||||
|
||||
// Include httpclient instrumentation for testing because it is a dependency for aws-sdk.
|
||||
testImplementation project(':instrumentation:apache-httpclient:apache-httpclient-4.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:apache-httpclient:apache-httpclient-4.0:javaagent')
|
||||
testLibrary group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.106'
|
||||
testLibrary group: 'com.amazonaws', name: 'aws-java-sdk-rds', version: '1.11.106'
|
||||
testLibrary group: 'com.amazonaws', name: 'aws-java-sdk-ec2', version: '1.11.106'
|
||||
|
|
|
@ -9,9 +9,7 @@ muzzle {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':instrumentation:aws-sdk:aws-sdk-2.2:library')) {
|
||||
exclude group: 'io.opentelemetry', module: 'opentelemetry-extension-trace-propagators'
|
||||
}
|
||||
implementation project(':instrumentation:aws-sdk:aws-sdk-2.2:library')
|
||||
|
||||
library group: 'software.amazon.awssdk', name: 'aws-core', version: '2.2.0'
|
||||
|
||||
|
@ -19,6 +17,4 @@ dependencies {
|
|||
// Make sure these don't add HTTP headers
|
||||
testImplementation project(':instrumentation:apache-httpclient:apache-httpclient-4.0:javaagent')
|
||||
testImplementation project(':instrumentation:netty:netty-4.1:javaagent')
|
||||
|
||||
testImplementation deps.opentelemetryTraceProps
|
||||
}
|
||||
|
|
|
@ -36,8 +36,16 @@ muzzle {
|
|||
dependencies {
|
||||
library group: 'com.datastax.cassandra', name: 'cassandra-driver-core', version: '3.0.0'
|
||||
|
||||
// Need to force version of Guava older than opentelemetry-sdk's implicit dependency to have one
|
||||
// that is compatible with Cassandra.
|
||||
testImplementation("com.google.guava:guava") {
|
||||
version {
|
||||
strictly("20.0")
|
||||
}
|
||||
}
|
||||
|
||||
testLibrary group: 'com.datastax.cassandra', name: 'cassandra-driver-core', version: '3.2.0'
|
||||
testImplementation project(':instrumentation:guava-10.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:guava-10.0:javaagent')
|
||||
|
||||
latestDepTestLibrary group: 'com.datastax.cassandra', name: 'cassandra-driver-core', version: '3.+'
|
||||
}
|
||||
|
|
|
@ -4,4 +4,12 @@ dependencies {
|
|||
compileOnly project(':javaagent-bootstrap')
|
||||
|
||||
testImplementation project(':javaagent-bootstrap')
|
||||
}
|
||||
|
||||
// TODO (trask) ResourceInjectionTest is sort of hybrid integration/unit test
|
||||
// maybe cleaner turning it into integration test with its own test instrumentation,
|
||||
// similar to :testing-common:integration-tests
|
||||
// then wouldn't need this shadowJar and wouldn't need HelperInjectorAccess
|
||||
shadowJar {
|
||||
from("src/test/resources/")
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
import static io.opentelemetry.instrumentation.util.gc.GcUtils.awaitGc
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.javaagent.tooling.HelperInjector
|
||||
import io.opentelemetry.javaagent.testing.common.HelperInjectorAccess
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
|
@ -15,7 +15,6 @@ class ResourceInjectionTest extends AgentTestRunner {
|
|||
def "resources injected to non-delegating classloader"() {
|
||||
setup:
|
||||
String resourceName = 'test-resources/test-resource.txt'
|
||||
HelperInjector injector = new HelperInjector("test", [], [resourceName])
|
||||
AtomicReference<URLClassLoader> emptyLoader = new AtomicReference<>(new URLClassLoader(new URL[0], (ClassLoader) null))
|
||||
|
||||
when:
|
||||
|
@ -26,7 +25,7 @@ class ResourceInjectionTest extends AgentTestRunner {
|
|||
when:
|
||||
URLClassLoader notInjectedLoader = new URLClassLoader(new URL[0], (ClassLoader) null)
|
||||
|
||||
injector.transform(null, null, emptyLoader.get(), null)
|
||||
HelperInjectorAccess.injectResources(emptyLoader.get(), resourceName)
|
||||
resourceUrls = emptyLoader.get().getResources(resourceName)
|
||||
|
||||
then:
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
*/
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State
|
||||
import org.apache.catalina.WebResource
|
||||
import org.apache.catalina.WebResourceRoot
|
||||
import org.apache.catalina.loader.ParallelWebappClassLoader
|
||||
|
@ -25,11 +24,8 @@ class TomcatClassloadingTest extends AgentTestRunner {
|
|||
classloader.init()
|
||||
classloader.start()
|
||||
|
||||
when:
|
||||
expect:
|
||||
// If instrumentation didn't work this would blow up with NPE due to incomplete resources mocking
|
||||
def clazz = classloader.loadClass("io.opentelemetry.javaagent.instrumentation.api.concurrent.State")
|
||||
|
||||
then:
|
||||
clazz == State
|
||||
classloader.loadClass("io.opentelemetry.javaagent.instrumentation.api.concurrent.State")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ dependencies {
|
|||
|
||||
library group: 'com.couchbase.client', name: 'java-client', version: '2.6.0'
|
||||
|
||||
testImplementation project(':instrumentation:couchbase:couchbase-2.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:couchbase:couchbase-2.0:javaagent')
|
||||
testImplementation project(':instrumentation:couchbase:couchbase-testing')
|
||||
|
||||
testLibrary group: 'org.springframework.data', name: 'spring-data-couchbase', version: '3.1.0.RELEASE'
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
ext {
|
||||
skipPublish = true
|
||||
}
|
||||
ext.skipPublish = true
|
||||
apply from: "$rootDir/gradle/instrumentation.gradle"
|
||||
|
||||
dependencies {
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-jersey-2.0:javaagent')
|
||||
testImplementation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-jersey-2.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
|
||||
// Need to force version of Guava older than opentelemetry-sdk's implicit dependency to have one
|
||||
// that is compatible with Dropwizard.
|
||||
testImplementation("com.google.guava:guava") {
|
||||
version {
|
||||
strictly("20.0")
|
||||
}
|
||||
}
|
||||
|
||||
// First version with DropwizardTestSupport:
|
||||
testImplementation group: 'io.dropwizard', name: 'dropwizard-testing', version: '0.8.0'
|
||||
|
|
|
@ -25,8 +25,8 @@ dependencies {
|
|||
|
||||
implementation project(':instrumentation:elasticsearch:elasticsearch-rest-common:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:apache-httpclient:apache-httpclient-4.0:javaagent')
|
||||
testImplementation project(':instrumentation:apache-httpasyncclient-4.1:javaagent')
|
||||
testInstrumentation project(':instrumentation:apache-httpclient:apache-httpclient-4.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:apache-httpasyncclient-4.1:javaagent')
|
||||
|
||||
testImplementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.0'
|
||||
testImplementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.0'
|
||||
|
|
|
@ -25,11 +25,11 @@ dependencies {
|
|||
|
||||
implementation project(':instrumentation:elasticsearch:elasticsearch-rest-common:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:apache-httpclient:apache-httpclient-4.0:javaagent')
|
||||
testImplementation project(':instrumentation:apache-httpasyncclient-4.1:javaagent')
|
||||
testInstrumentation project(':instrumentation:apache-httpclient:apache-httpclient-4.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:apache-httpasyncclient-4.1:javaagent')
|
||||
//TODO: review the following claim, we are not using embedded ES anymore
|
||||
// Netty is used, but it adds complexity to the tests since we're using embedded ES.
|
||||
//testImplementation project(':instrumentation:netty:netty-4.1:javaagent')
|
||||
//testInstrumentation project(':instrumentation:netty:netty-4.1:javaagent')
|
||||
|
||||
testImplementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.0'
|
||||
testImplementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.0'
|
||||
|
|
|
@ -21,9 +21,9 @@ dependencies {
|
|||
implementation project(':instrumentation:elasticsearch:elasticsearch-transport-common:javaagent')
|
||||
|
||||
// Ensure no cross interference
|
||||
testImplementation project(':instrumentation:elasticsearch:elasticsearch-rest-5.0:javaagent')
|
||||
testImplementation project(':instrumentation:apache-httpasyncclient-4.1:javaagent')
|
||||
testImplementation project(':instrumentation:netty:netty-4.1:javaagent')
|
||||
testInstrumentation project(':instrumentation:elasticsearch:elasticsearch-rest-5.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:apache-httpasyncclient-4.1:javaagent')
|
||||
testInstrumentation project(':instrumentation:netty:netty-4.1:javaagent')
|
||||
|
||||
testImplementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.0'
|
||||
testImplementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.0'
|
||||
|
|
|
@ -20,9 +20,9 @@ dependencies {
|
|||
|
||||
implementation project(':instrumentation:elasticsearch:elasticsearch-transport-common:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:apache-httpasyncclient-4.1:javaagent')
|
||||
testImplementation project(':instrumentation:netty:netty-4.1:javaagent')
|
||||
testImplementation project(':instrumentation:spring:spring-data-1.8:javaagent')
|
||||
testInstrumentation project(':instrumentation:apache-httpasyncclient-4.1:javaagent')
|
||||
testInstrumentation project(':instrumentation:netty:netty-4.1:javaagent')
|
||||
testInstrumentation project(':instrumentation:spring:spring-data-1.8:javaagent')
|
||||
|
||||
testImplementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.0'
|
||||
testImplementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.0'
|
||||
|
|
|
@ -29,9 +29,9 @@ dependencies {
|
|||
implementation project(':instrumentation:elasticsearch:elasticsearch-transport-common:javaagent')
|
||||
|
||||
// Ensure no cross interference
|
||||
testImplementation project(':instrumentation:elasticsearch:elasticsearch-rest-5.0:javaagent')
|
||||
testImplementation project(':instrumentation:apache-httpasyncclient-4.1:javaagent')
|
||||
testImplementation project(':instrumentation:netty:netty-4.1:javaagent')
|
||||
testInstrumentation project(':instrumentation:elasticsearch:elasticsearch-rest-5.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:apache-httpasyncclient-4.1:javaagent')
|
||||
testInstrumentation project(':instrumentation:netty:netty-4.1:javaagent')
|
||||
|
||||
testLibrary group: 'org.elasticsearch.plugin', name: 'transport-netty4-client', version: '6.0.0'
|
||||
|
||||
|
|
|
@ -5,3 +5,7 @@ muzzle {
|
|||
coreJdk()
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
jvmArgs "-Dotel.instrumentation.executors.include=ExecutorInstrumentationTest\$CustomThreadPoolExecutor"
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import io.opentelemetry.sdk.trace.data.SpanData
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.util.concurrent.AbstractExecutorService
|
||||
|
@ -26,13 +25,6 @@ import java.util.concurrent.TimeoutException
|
|||
import spock.lang.Shared
|
||||
|
||||
class ExecutorInstrumentationTest extends AgentTestRunner {
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfigAndResetInstrumentation {
|
||||
it.setProperty("otel.instrumentation.executors.include", "ExecutorInstrumentationTest\$CustomThreadPoolExecutor")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
@Shared
|
||||
def executeRunnable = { e, c -> e.execute((Runnable) c) }
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
apply from: "$rootDir/gradle/java.gradle"
|
||||
|
||||
dependencies {
|
||||
testImplementation project(':instrumentation-api')
|
||||
testImplementation project(':javaagent-tooling')
|
||||
testImplementation deps.bytebuddy
|
||||
testImplementation project(':instrumentation:external-annotations:javaagent')
|
||||
}
|
|
@ -26,15 +26,19 @@ dependencies {
|
|||
|
||||
test {
|
||||
filter {
|
||||
excludeTestsMatching 'TraceProvidersTest'
|
||||
excludeTestsMatching 'ConfiguredTraceAnnotationsTest'
|
||||
excludeTestsMatching 'TracedMethodsExclusionTest'
|
||||
}
|
||||
}
|
||||
|
||||
// Needs a fresh classloader.
|
||||
// https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/919
|
||||
def testTraceProviders = tasks.register('testTraceProviders', Test) {
|
||||
test.finalizedBy(tasks.register("testIncludeProperty", Test) {
|
||||
filter {
|
||||
includeTestsMatching 'TraceProvidersTest'
|
||||
includeTestsMatching 'ConfiguredTraceAnnotationsTest'
|
||||
}
|
||||
}
|
||||
test.dependsOn(testTraceProviders)
|
||||
jvmArgs "-Dotel.instrumentation.external-annotations.include=package.Class\$Name;OuterClass\$InterestingMethod"
|
||||
})
|
||||
test.finalizedBy(tasks.register("testExcludeMethodsProperty", Test) {
|
||||
filter {
|
||||
includeTestsMatching 'TracedMethodsExclusionTest'
|
||||
}
|
||||
jvmArgs "-Dotel.instrumentation.external-annotations.exclude-methods=TracedMethodsExclusionTest\$TestClass[excluded,annotatedButExcluded]"
|
||||
})
|
||||
|
|
|
@ -4,19 +4,10 @@
|
|||
*/
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import io.opentelemetry.test.annotation.SayTracedHello
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
class ConfiguredTraceAnnotationsTest extends AgentTestRunner {
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfigAndResetInstrumentation {
|
||||
it.setProperty("otel.instrumentation.external-annotations.include",
|
||||
"package.Class\$Name;${OuterClass.InterestingMethod.name}")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
def "method with disabled NewRelic annotation should be ignored"() {
|
||||
setup:
|
||||
|
|
|
@ -4,18 +4,9 @@
|
|||
*/
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import io.opentracing.contrib.dropwizard.Trace
|
||||
|
||||
class TracedMethodsExclusionTest extends AgentTestRunner {
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfigAndResetInstrumentation {
|
||||
it.setProperty("otel.instrumentation.external-annotations.exclude-methods",
|
||||
"${TestClass.name}[excluded,annotatedButExcluded]")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
static class TestClass {
|
||||
//This method is not mentioned in any configuration
|
||||
|
|
|
@ -28,7 +28,8 @@ dependencies {
|
|||
// here.
|
||||
compileOnly group: 'com.twitter', name: 'finatra-http_2.11', version: '2.9.0'
|
||||
|
||||
testImplementation project(':instrumentation:netty:netty-4.1:javaagent')
|
||||
testInstrumentation project(':instrumentation:netty:netty-4.1:javaagent')
|
||||
|
||||
testImplementation group: 'com.twitter', name: 'finatra-http_2.11', version: '19.12.0'
|
||||
testImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.10'
|
||||
// Required for older versions of finatra on JDKs >= 11
|
||||
|
|
|
@ -12,6 +12,13 @@ muzzle {
|
|||
dependencies {
|
||||
compileOnly group: 'org.glassfish.grizzly', name: 'grizzly-http', version: '2.0'
|
||||
|
||||
// Need to force version of Guava older than opentelemetry-sdk's implicit dependency to have one
|
||||
// that is compatible with Grizzly.
|
||||
testImplementation("com.google.guava:guava") {
|
||||
version {
|
||||
strictly("20.0")
|
||||
}
|
||||
}
|
||||
testImplementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3'
|
||||
testImplementation group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0'
|
||||
testLibrary group: 'org.glassfish.jersey.containers', name: 'jersey-container-grizzly2-http', version: '2.0'
|
||||
|
@ -19,3 +26,7 @@ dependencies {
|
|||
latestDepTestLibrary group: 'org.glassfish.jersey.containers', name: 'jersey-container-grizzly2-http', version: '2.+'
|
||||
latestDepTestLibrary group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: '2.+'
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
jvmArgs "-Dotel.instrumentation.grizzly.enabled=true"
|
||||
}
|
|
@ -38,10 +38,6 @@ import org.glassfish.grizzly.utils.IdleTimeoutFilter
|
|||
|
||||
class GrizzlyFilterchainServerTest extends HttpServerTest<HttpServer> {
|
||||
|
||||
static {
|
||||
System.setProperty("otel.instrumentation.grizzly.enabled", "true")
|
||||
}
|
||||
|
||||
private TCPNIOTransport transport
|
||||
private TCPNIOServerConnection serverConnection
|
||||
|
||||
|
|
|
@ -22,10 +22,6 @@ import org.glassfish.jersey.server.ResourceConfig
|
|||
|
||||
class GrizzlyTest extends HttpServerTest<HttpServer> {
|
||||
|
||||
static {
|
||||
System.setProperty("otel.instrumentation.grizzly.enabled", "true")
|
||||
}
|
||||
|
||||
@Override
|
||||
HttpServer startServer(int port) {
|
||||
ResourceConfig rc = new ResourceConfig()
|
||||
|
|
|
@ -21,10 +21,10 @@ dependencies {
|
|||
|
||||
implementation project(':instrumentation:hibernate:hibernate-common:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:jdbc:javaagent')
|
||||
testInstrumentation project(':instrumentation:jdbc:javaagent')
|
||||
// Added to ensure cross compatibility:
|
||||
testImplementation project(':instrumentation:hibernate:hibernate-4.0:javaagent')
|
||||
testImplementation project(':instrumentation:hibernate:hibernate-4.3:javaagent')
|
||||
testInstrumentation project(':instrumentation:hibernate:hibernate-4.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:hibernate:hibernate-4.3:javaagent')
|
||||
|
||||
testLibrary group: 'org.hibernate', name: 'hibernate-core', version: '3.3.0.SP1'
|
||||
testImplementation group: 'org.hibernate', name: 'hibernate-annotations', version: '3.4.0.GA'
|
||||
|
|
|
@ -14,10 +14,10 @@ dependencies {
|
|||
|
||||
implementation project(':instrumentation:hibernate:hibernate-common:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:jdbc:javaagent')
|
||||
testInstrumentation project(':instrumentation:jdbc:javaagent')
|
||||
// Added to ensure cross compatibility:
|
||||
testImplementation project(':instrumentation:hibernate:hibernate-3.3:javaagent')
|
||||
testImplementation project(':instrumentation:hibernate:hibernate-4.3:javaagent')
|
||||
testInstrumentation project(':instrumentation:hibernate:hibernate-3.3:javaagent')
|
||||
testInstrumentation project(':instrumentation:hibernate:hibernate-4.3:javaagent')
|
||||
|
||||
testImplementation group: 'com.h2database', name: 'h2', version: '1.4.197'
|
||||
testImplementation "javax.xml.bind:jaxb-api:2.2.11"
|
||||
|
|
|
@ -14,10 +14,10 @@ dependencies {
|
|||
|
||||
implementation project(':instrumentation:hibernate:hibernate-common:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:jdbc:javaagent')
|
||||
testInstrumentation project(':instrumentation:jdbc:javaagent')
|
||||
// Added to ensure cross compatibility:
|
||||
testImplementation project(':instrumentation:hibernate:hibernate-3.3:javaagent')
|
||||
testImplementation project(':instrumentation:hibernate:hibernate-4.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:hibernate:hibernate-3.3:javaagent')
|
||||
testInstrumentation project(':instrumentation:hibernate:hibernate-4.0:javaagent')
|
||||
|
||||
testLibrary group: 'org.hibernate', name: 'hibernate-entitymanager', version: '4.3.0.Final'
|
||||
testImplementation group: 'org.hsqldb', name: 'hsqldb', version: '2.0.0'
|
||||
|
|
|
@ -14,3 +14,13 @@ dependencies {
|
|||
library group: 'com.netflix.hystrix', name: 'hystrix-core', version: '1.4.0'
|
||||
library group: 'io.reactivex', name: 'rxjava', version: '1.0.7'
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
// TODO run tests both with and without experimental span attributes
|
||||
jvmArgs "-Dotel.instrumentation.hystrix.experimental-span-attributes=true"
|
||||
// Disable so failure testing below doesn't inadvertently change the behavior.
|
||||
jvmArgs "-Dhystrix.command.default.circuitBreaker.enabled=false"
|
||||
|
||||
// Uncomment for debugging:
|
||||
// jvmArgs "-Dhystrix.command.default.execution.timeout.enabled=false"
|
||||
}
|
||||
|
|
|
@ -8,26 +8,10 @@ import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTra
|
|||
|
||||
import com.netflix.hystrix.HystrixObservableCommand
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import rx.Observable
|
||||
import rx.schedulers.Schedulers
|
||||
|
||||
class HystrixObservableChainTest extends AgentTestRunner {
|
||||
static {
|
||||
// Disable so failure testing below doesn't inadvertently change the behavior.
|
||||
System.setProperty("hystrix.command.default.circuitBreaker.enabled", "false")
|
||||
|
||||
// Uncomment for debugging:
|
||||
// System.setProperty("hystrix.command.default.execution.timeout.enabled", "false")
|
||||
}
|
||||
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfig {
|
||||
it.setProperty("otel.instrumentation.hystrix.experimental-span-attributes", "true")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
def "test command #action"() {
|
||||
setup:
|
||||
|
|
|
@ -10,28 +10,12 @@ import com.netflix.hystrix.HystrixObservable
|
|||
import com.netflix.hystrix.HystrixObservableCommand
|
||||
import com.netflix.hystrix.exception.HystrixRuntimeException
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import java.util.concurrent.BlockingQueue
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
import rx.Observable
|
||||
import rx.schedulers.Schedulers
|
||||
|
||||
class HystrixObservableTest extends AgentTestRunner {
|
||||
static {
|
||||
// Disable so failure testing below doesn't inadvertently change the behavior.
|
||||
System.setProperty("hystrix.command.default.circuitBreaker.enabled", "false")
|
||||
|
||||
// Uncomment for debugging:
|
||||
// System.setProperty("hystrix.command.default.execution.timeout.enabled", "false")
|
||||
}
|
||||
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfig {
|
||||
it.setProperty("otel.instrumentation.hystrix.experimental-span-attributes", "true")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
def "test command #action"() {
|
||||
setup:
|
||||
|
@ -62,7 +46,6 @@ class HystrixObservableTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
expect:
|
||||
TRANSFORMED_CLASSES_NAMES.contains("HystrixObservableTest\$1")
|
||||
result == "Hello!"
|
||||
|
||||
assertTraces(1) {
|
||||
|
@ -157,7 +140,6 @@ class HystrixObservableTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
expect:
|
||||
TRANSFORMED_CLASSES_NAMES.contains("HystrixObservableTest\$2")
|
||||
result == "Fallback!"
|
||||
|
||||
assertTraces(1) {
|
||||
|
@ -254,7 +236,6 @@ class HystrixObservableTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
then:
|
||||
TRANSFORMED_CLASSES_NAMES.contains("HystrixObservableTest\$3")
|
||||
def err = thrown HystrixRuntimeException
|
||||
err.cause instanceof IllegalArgumentException
|
||||
|
||||
|
|
|
@ -8,28 +8,12 @@ import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTra
|
|||
|
||||
import com.netflix.hystrix.HystrixCommand
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import java.util.concurrent.BlockingQueue
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
import spock.lang.Timeout
|
||||
|
||||
@Timeout(10)
|
||||
class HystrixTest extends AgentTestRunner {
|
||||
static {
|
||||
// Disable so failure testing below doesn't inadvertently change the behavior.
|
||||
System.setProperty("hystrix.command.default.circuitBreaker.enabled", "false")
|
||||
|
||||
// Uncomment for debugging:
|
||||
// System.setProperty("hystrix.command.default.execution.timeout.enabled", "false")
|
||||
}
|
||||
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfig {
|
||||
it.setProperty("otel.instrumentation.hystrix.experimental-span-attributes", "true")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
def "test command #action"() {
|
||||
setup:
|
||||
|
@ -48,7 +32,6 @@ class HystrixTest extends AgentTestRunner {
|
|||
operation(command)
|
||||
}
|
||||
expect:
|
||||
TRANSFORMED_CLASSES_NAMES.contains("HystrixTest\$1")
|
||||
result == "Hello!"
|
||||
|
||||
assertTraces(1) {
|
||||
|
@ -111,7 +94,6 @@ class HystrixTest extends AgentTestRunner {
|
|||
operation(command)
|
||||
}
|
||||
expect:
|
||||
TRANSFORMED_CLASSES_NAMES.contains("HystrixTest\$2")
|
||||
result == "Fallback!"
|
||||
|
||||
assertTraces(1) {
|
||||
|
|
|
@ -73,6 +73,9 @@ shadowJar {
|
|||
relocate "io.opentelemetry.api", "io.opentelemetry.javaagent.shaded.io.opentelemetry.api"
|
||||
relocate "io.opentelemetry.spi", "io.opentelemetry.javaagent.shaded.io.opentelemetry.spi"
|
||||
relocate "io.opentelemetry.context", "io.opentelemetry.javaagent.shaded.io.opentelemetry.context"
|
||||
|
||||
// relocate OpenTelemetry extensions
|
||||
relocate "io.opentelemetry.extension.kotlin", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.kotlin"
|
||||
relocate "io.opentelemetry.extension.trace.propagation", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.trace.propagation"
|
||||
|
||||
// this is for instrumentation on opentelemetry-api itself
|
||||
|
|
|
@ -19,8 +19,17 @@ dependencies {
|
|||
compileOnly group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0.1'
|
||||
compileOnly group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'
|
||||
|
||||
testImplementation project(':instrumentation:jaxrs-client:jaxrs-client-2.0:jaxrs-client-2.0-jersey-2.0:javaagent')
|
||||
testImplementation project(':instrumentation:jaxrs-client:jaxrs-client-2.0:jaxrs-client-2.0-resteasy-2.0:javaagent')
|
||||
|
||||
// Need to force version of Guava older than opentelemetry-sdk's implicit dependency to have one
|
||||
// that is compatible with Jersey.
|
||||
testImplementation("com.google.guava:guava") {
|
||||
version {
|
||||
strictly("20.0")
|
||||
}
|
||||
}
|
||||
|
||||
testInstrumentation project(':instrumentation:jaxrs-client:jaxrs-client-2.0:jaxrs-client-2.0-jersey-2.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:jaxrs-client:jaxrs-client-2.0:jaxrs-client-2.0-resteasy-2.0:javaagent')
|
||||
|
||||
testImplementation group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0.1'
|
||||
|
||||
|
@ -33,7 +42,7 @@ dependencies {
|
|||
|
||||
testImplementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3'
|
||||
|
||||
testImplementation project(':instrumentation:apache-httpclient:apache-httpclient-4.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:apache-httpclient:apache-httpclient-4.0:javaagent')
|
||||
|
||||
latestDepTestLibrary group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: '2.27'
|
||||
latestDepTestLibrary group: 'org.glassfish.jersey.core', name: 'jersey-client', version: '2.27'
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderServerTrace
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.javaagent.instrumentation.api.WeakMap
|
||||
import io.opentelemetry.javaagent.instrumentation.jaxrs.v1_0.JaxRsAnnotationsTracer
|
||||
import java.lang.reflect.Method
|
||||
import javax.ws.rs.DELETE
|
||||
import javax.ws.rs.GET
|
||||
import javax.ws.rs.HEAD
|
||||
|
@ -40,9 +37,8 @@ class JaxRsAnnotations1InstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
|
||||
def "span named '#name' from annotations on class when is not root span"() {
|
||||
def "span named '#paramName' from annotations on class when is not root span"() {
|
||||
setup:
|
||||
def startingCacheSize = spanNames.size()
|
||||
runUnderServerTrace("test") {
|
||||
obj.call()
|
||||
}
|
||||
|
@ -64,8 +60,6 @@ class JaxRsAnnotations1InstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
}
|
||||
spanNames.size() == startingCacheSize + 1
|
||||
spanNames.get(obj.class).size() == 1
|
||||
|
||||
when: "multiple calls to the same method"
|
||||
runUnderServerTrace("test") {
|
||||
|
@ -74,8 +68,6 @@ class JaxRsAnnotations1InstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
then: "doesn't increase the cache size"
|
||||
spanNames.size() == startingCacheSize + 1
|
||||
spanNames.get(obj.class).size() == 1
|
||||
|
||||
where:
|
||||
paramName | obj
|
||||
|
@ -129,10 +121,6 @@ class JaxRsAnnotations1InstrumentationTest extends AgentTestRunner {
|
|||
// "/child/invoke" | new JavaInterfaces.DefaultChildClassOnInterface()
|
||||
|
||||
className = getClassName(obj.class)
|
||||
|
||||
// JavaInterfaces classes are loaded on a different classloader, so we need to find the right cache instance.
|
||||
decorator = obj.class.classLoader.loadClass(JaxRsAnnotationsTracer.name).getMethod("tracer").invoke(null)
|
||||
spanNames = (WeakMap<Class, Map<Method, String>>) decorator.spanNames
|
||||
}
|
||||
|
||||
def "no annotations has no effect"() {
|
||||
|
|
|
@ -16,7 +16,8 @@ dependencies {
|
|||
|
||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
||||
|
||||
// First version with DropwizardTestSupport:
|
||||
|
|
|
@ -26,7 +26,8 @@ dependencies {
|
|||
|
||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
||||
|
||||
testLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.0.4.Final') {
|
||||
|
|
|
@ -26,7 +26,8 @@ dependencies {
|
|||
|
||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
||||
|
||||
testLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.1.0.Final') {
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderServerTrace
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.javaagent.instrumentation.api.WeakMap
|
||||
import io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer
|
||||
import java.lang.reflect.Method
|
||||
import javax.ws.rs.DELETE
|
||||
import javax.ws.rs.GET
|
||||
import javax.ws.rs.HEAD
|
||||
|
@ -44,7 +41,6 @@ abstract class JaxRsAnnotationsInstrumentationTest extends AgentTestRunner {
|
|||
@Unroll
|
||||
def "span named '#paramName' from annotations on class when is not root span"() {
|
||||
setup:
|
||||
def startingCacheSize = spanNames.size()
|
||||
runUnderServerTrace("test") {
|
||||
obj.call()
|
||||
}
|
||||
|
@ -66,8 +62,6 @@ abstract class JaxRsAnnotationsInstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
}
|
||||
spanNames.size() == startingCacheSize + 1
|
||||
spanNames.get(obj.class).size() == 1
|
||||
|
||||
when: "multiple calls to the same method"
|
||||
runUnderServerTrace("test") {
|
||||
|
@ -76,8 +70,6 @@ abstract class JaxRsAnnotationsInstrumentationTest extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
then: "doesn't increase the cache size"
|
||||
spanNames.size() == startingCacheSize + 1
|
||||
spanNames.get(obj.class).size() == 1
|
||||
|
||||
where:
|
||||
paramName | obj
|
||||
|
@ -131,10 +123,6 @@ abstract class JaxRsAnnotationsInstrumentationTest extends AgentTestRunner {
|
|||
// "GET /child/invoke" | new JavaInterfaces.DefaultChildClassOnInterface()
|
||||
|
||||
className = getClassName(obj.class)
|
||||
|
||||
// JavaInterfaces classes are loaded on a different classloader, so we need to find the right cache instance.
|
||||
decorator = obj.class.classLoader.loadClass(JaxRsAnnotationsTracer.name).getMethod("tracer").invoke(null)
|
||||
spanNames = (WeakMap<Class, Map<Method, String>>) decorator.spanNames
|
||||
}
|
||||
|
||||
def "no annotations has no effect"() {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
apply from: "$rootDir/gradle/java.gradle"
|
||||
|
||||
dependencies {
|
||||
testImplementation project(':instrumentation:jdbc:javaagent')
|
||||
}
|
|
@ -22,3 +22,6 @@ dependencies {
|
|||
latestDepTestLibrary group: 'org.apache.derby', name: 'derby', version: '10.14.+'
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
jvmArgs "-Dotel.instrumentation.jdbc-datasource.enabled=true"
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import com.zaxxer.hikari.HikariConfig
|
|||
import com.zaxxer.hikari.HikariDataSource
|
||||
import io.opentelemetry.api.trace.attributes.SemanticAttributes
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import java.sql.CallableStatement
|
||||
import java.sql.Connection
|
||||
import java.sql.PreparedStatement
|
||||
|
@ -30,13 +29,6 @@ import test.TestConnection
|
|||
import test.TestDriver
|
||||
|
||||
class JdbcInstrumentationTest extends AgentTestRunner {
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfigAndResetInstrumentation {
|
||||
it.setProperty("otel.instrumentation.jdbc-datasource.enabled", "true")
|
||||
}
|
||||
|
||||
def specCleanup() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
@Shared
|
||||
def dbName = "jdbcUnitTest"
|
||||
|
|
|
@ -20,7 +20,7 @@ dependencies {
|
|||
testImplementation group: 'com.github.kstyrc', name: 'embedded-redis', version: '0.6'
|
||||
// ensures jedis-1.4 instrumentation does not load with jedis 3.0+ by failing
|
||||
// the tests in the event it does. The tests will end up with double spans
|
||||
testImplementation project(':instrumentation:jedis:jedis-1.4:javaagent')
|
||||
testInstrumentation project(':instrumentation:jedis:jedis-1.4:javaagent')
|
||||
|
||||
testLibrary group: 'redis.clients', name: 'jedis', version: '3.+'
|
||||
}
|
||||
|
|
|
@ -18,17 +18,21 @@ class SpringListenerJms2Test extends AgentTestRunner {
|
|||
def context = new AnnotationConfigApplicationContext(Config)
|
||||
def factory = context.getBean(ConnectionFactory)
|
||||
def template = new JmsTemplate(factory)
|
||||
// TODO(anuraaga): There is no defined order between when JMS starts receiving and our attempt
|
||||
// to send/receive. Sleep a bit to let JMS start to receive first. Ideally, we would not have
|
||||
// an ordering constraint in our assertTraces for when there is no defined ordering like this
|
||||
// test case.
|
||||
template.convertAndSend("SpringListenerJms2", "a message")
|
||||
|
||||
expect:
|
||||
assertTraces(2) {
|
||||
trace(0, 2) {
|
||||
trace(0, 1) {
|
||||
consumerSpan(it, 0, "queue", "SpringListenerJms2", "", null, "receive")
|
||||
}
|
||||
trace(1, 2) {
|
||||
producerSpan(it, 0, "queue", "SpringListenerJms2")
|
||||
consumerSpan(it, 1, "queue", "SpringListenerJms2", "", span(0), "process")
|
||||
}
|
||||
trace(1, 1) {
|
||||
consumerSpan(it, 0, "queue", "SpringListenerJms2", "", null, "receive")
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
|
|
@ -119,16 +119,16 @@ class SpringTemplateJms2Test extends AgentTestRunner {
|
|||
receivedMessage.text == "responded!"
|
||||
assertTraces(4) {
|
||||
trace(0, 1) {
|
||||
producerSpan(it, 0, destinationType, destinationName)
|
||||
}
|
||||
trace(1, 1) {
|
||||
consumerSpan(it, 0, destinationType, destinationName, msgId.get(), null, "receive")
|
||||
}
|
||||
trace(1, 1) {
|
||||
producerSpan(it, 0, destinationType, destinationName)
|
||||
}
|
||||
trace(2, 1) {
|
||||
producerSpan(it, 0, "queue", "(temporary)")
|
||||
consumerSpan(it, 0, "queue", "(temporary)", receivedMessage.getJMSMessageID(), null, "receive")
|
||||
}
|
||||
trace(3, 1) {
|
||||
consumerSpan(it, 0, "queue", "(temporary)", receivedMessage.getJMSMessageID(), null, "receive")
|
||||
producerSpan(it, 0, "queue", "(temporary)")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,17 +19,22 @@ class SpringListenerJms1Test extends AgentTestRunner {
|
|||
def context = new AnnotationConfigApplicationContext(Config)
|
||||
def factory = context.getBean(ConnectionFactory)
|
||||
def template = new JmsTemplate(factory)
|
||||
// TODO(anuraaga): There is no defined order between when JMS starts receiving and our attempt
|
||||
// to send/receive. Sleep a bit to let JMS start to receive first. Ideally, we would not have
|
||||
// an ordering constraint in our assertTraces for when there is no defined ordering like this
|
||||
// test case.
|
||||
sleep(500)
|
||||
template.convertAndSend("SpringListenerJms1", "a message")
|
||||
|
||||
expect:
|
||||
assertTraces(2) {
|
||||
trace(0, 2) {
|
||||
trace(0, 1) {
|
||||
consumerSpan(it, 0, "queue", "SpringListenerJms1", "", null, "receive")
|
||||
}
|
||||
trace(1, 2) {
|
||||
producerSpan(it, 0, "queue", "SpringListenerJms1")
|
||||
consumerSpan(it, 1, "queue", "SpringListenerJms1", "", span(0), "process")
|
||||
}
|
||||
trace(1, 1) {
|
||||
consumerSpan(it, 0, "queue", "SpringListenerJms1", "", null, "receive")
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
|
|
@ -98,17 +98,17 @@ class SpringTemplateJms1Test extends AgentTestRunner {
|
|||
receivedMessage.text == "responded!"
|
||||
assertTraces(4) {
|
||||
trace(0, 1) {
|
||||
producerSpan(it, 0, destinationType, destinationName)
|
||||
}
|
||||
trace(1, 1) {
|
||||
consumerSpan(it, 0, destinationType, destinationName, msgId.get(), null, "receive")
|
||||
}
|
||||
trace(1, 1) {
|
||||
producerSpan(it, 0, destinationType, destinationName)
|
||||
}
|
||||
trace(2, 1) {
|
||||
// receive doesn't propagate the trace, so this is a root
|
||||
producerSpan(it, 0, "queue", "(temporary)")
|
||||
consumerSpan(it, 0, "queue", "(temporary)", receivedMessage.getJMSMessageID(), null, "receive")
|
||||
}
|
||||
trace(3, 1) {
|
||||
consumerSpan(it, 0, "queue", "(temporary)", receivedMessage.getJMSMessageID(), null, "receive")
|
||||
// receive doesn't propagate the trace, so this is a root
|
||||
producerSpan(it, 0, "queue", "(temporary)")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ dependencies {
|
|||
compileOnly group: 'javax.servlet.jsp', name: 'javax.servlet.jsp-api', version: '2.3.0'
|
||||
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
|
||||
|
||||
testImplementation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||
// using tomcat 7.0.37 because there seems to be some issues with Tomcat's jar scanning in versions < 7.0.37
|
||||
// https://stackoverflow.com/questions/23484098/org-apache-tomcat-util-bcel-classfile-classformatexception-invalid-byte-tag-in
|
||||
testLibrary group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '7.0.37'
|
||||
|
@ -28,3 +28,12 @@ dependencies {
|
|||
latestDepTestLibrary group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '9.+'
|
||||
latestDepTestLibrary group: 'org.apache.tomcat.embed', name: 'tomcat-embed-logging-juli', version: '9.+'
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
// skip jar scanning using environment variables:
|
||||
// http://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html#JAR_Scanning
|
||||
// having this set allows us to test with old versions of the tomcat api since
|
||||
// JarScanFilter did not exist in the tomcat 7 api
|
||||
jvmArgs '-Dorg.apache.catalina.startup.ContextConfig.jarsToSkip=*'
|
||||
jvmArgs '-Dorg.apache.catalina.startup.TldConfig.jarsToSkip=*'
|
||||
}
|
||||
|
|
|
@ -24,15 +24,6 @@ import spock.lang.Unroll
|
|||
//TODO should this be HttpServerTest?
|
||||
class JspInstrumentationBasicTests extends AgentTestRunner {
|
||||
|
||||
static {
|
||||
// skip jar scanning using environment variables:
|
||||
// http://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html#JAR_Scanning
|
||||
// having this set allows us to test with old versions of the tomcat api since
|
||||
// JarScanFilter did not exist in the tomcat 7 api
|
||||
System.setProperty("org.apache.catalina.startup.ContextConfig.jarsToSkip", "*")
|
||||
System.setProperty("org.apache.catalina.startup.TldConfig.jarsToSkip", "*")
|
||||
}
|
||||
|
||||
@Shared
|
||||
int port
|
||||
@Shared
|
||||
|
|
|
@ -21,15 +21,6 @@ import spock.lang.Unroll
|
|||
|
||||
class JspInstrumentationForwardTests extends AgentTestRunner {
|
||||
|
||||
static {
|
||||
// skip jar scanning using environment variables:
|
||||
// http://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html#JAR_Scanning
|
||||
// having this set allows us to test with old versions of the tomcat api since
|
||||
// JarScanFilter did not exist in the tomcat 7 api
|
||||
System.setProperty("org.apache.catalina.startup.ContextConfig.jarsToSkip", "*")
|
||||
System.setProperty("org.apache.catalina.startup.TldConfig.jarsToSkip", "*")
|
||||
}
|
||||
|
||||
@Shared
|
||||
int port
|
||||
@Shared
|
||||
|
|
|
@ -28,3 +28,19 @@ dependencies {
|
|||
latestDepTestLibrary group: 'org.springframework.kafka', name: 'spring-kafka-test', version: '2.2.+'
|
||||
latestDepTestLibrary group: 'org.assertj', name: 'assertj-core', version: '3.+'
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
// TODO run tests both with and without experimental span attributes
|
||||
jvmArgs "-Dotel.instrumentation.kafka.experimental-span-attributes=true"
|
||||
}
|
||||
test {
|
||||
filter {
|
||||
excludeTestsMatching 'KafkaClientPropagationDisabledTest'
|
||||
}
|
||||
}
|
||||
test.finalizedBy(tasks.register("testPropagationDisabled", Test) {
|
||||
filter {
|
||||
includeTestsMatching 'KafkaClientPropagationDisabledTest'
|
||||
}
|
||||
jvmArgs "-Dotel.instrumentation.kafka.client-propagation=false"
|
||||
})
|
||||
|
|
|
@ -22,9 +22,8 @@ abstract class KafkaClientBaseTest extends AgentTestRunner {
|
|||
|
||||
protected static final SHARED_TOPIC = "shared.topic"
|
||||
|
||||
protected isPropagationEnabled() {
|
||||
return true
|
||||
}
|
||||
private static final boolean propagationEnabled = Boolean.parseBoolean(
|
||||
System.getProperty("otel.instrumentation.kafka.client-propagation", "true"))
|
||||
|
||||
@Rule
|
||||
KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, SHARED_TOPIC)
|
||||
|
@ -73,7 +72,7 @@ abstract class KafkaClientBaseTest extends AgentTestRunner {
|
|||
// check that the message was received
|
||||
def received = records.poll(5, TimeUnit.SECONDS)
|
||||
|
||||
received.headers().iterator().hasNext() == isPropagationEnabled()
|
||||
received.headers().iterator().hasNext() == propagationEnabled
|
||||
|
||||
cleanup:
|
||||
producerFactory.stop()
|
||||
|
|
|
@ -7,7 +7,6 @@ import static io.opentelemetry.api.trace.Span.Kind.CONSUMER
|
|||
import static io.opentelemetry.api.trace.Span.Kind.PRODUCER
|
||||
|
||||
import io.opentelemetry.api.trace.attributes.SemanticAttributes
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
import java.util.concurrent.TimeUnit
|
||||
import org.apache.kafka.clients.consumer.ConsumerConfig
|
||||
|
@ -21,20 +20,6 @@ import org.springframework.kafka.test.utils.ContainerTestUtils
|
|||
import org.springframework.kafka.test.utils.KafkaTestUtils
|
||||
|
||||
class KafkaClientPropagationDisabledTest extends KafkaClientBaseTest {
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfigAndResetInstrumentation {
|
||||
it.setProperty("otel.instrumentation.kafka.client-propagation", "false")
|
||||
// TODO run tests both with and without experimental span attributes
|
||||
it.setProperty("otel.instrumentation.kafka.experimental-span-attributes", "true")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected isPropagationEnabled() {
|
||||
return false
|
||||
}
|
||||
|
||||
def "should not read remote context when consuming messages if propagation is disabled"() {
|
||||
setup:
|
||||
|
|
|
@ -9,7 +9,6 @@ import static io.opentelemetry.instrumentation.test.utils.TraceUtils.basicSpan
|
|||
import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
|
||||
|
||||
import io.opentelemetry.api.trace.attributes.SemanticAttributes
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
import java.util.concurrent.TimeUnit
|
||||
import org.apache.kafka.clients.consumer.ConsumerConfig
|
||||
|
@ -29,14 +28,6 @@ import org.springframework.kafka.test.utils.ContainerTestUtils
|
|||
import org.springframework.kafka.test.utils.KafkaTestUtils
|
||||
|
||||
class KafkaClientPropagationEnabledTest extends KafkaClientBaseTest {
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfigAndResetInstrumentation {
|
||||
// TODO run tests both with and without experimental span attributes
|
||||
it.setProperty("otel.instrumentation.kafka.experimental-span-attributes", "true")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
def "test kafka produce and consume"() {
|
||||
setup:
|
||||
|
|
|
@ -12,7 +12,7 @@ dependencies {
|
|||
library group: 'org.apache.kafka', name: 'kafka-streams', version: '0.11.0.0'
|
||||
|
||||
// Include kafka-clients instrumentation for tests.
|
||||
testImplementation project(':instrumentation:kafka-clients-0.11:javaagent')
|
||||
testInstrumentation project(':instrumentation:kafka-clients-0.11:javaagent')
|
||||
|
||||
testLibrary group: 'org.apache.kafka', name: 'kafka-clients', version: '0.11.0.0'
|
||||
testLibrary group: 'org.springframework.kafka', name: 'spring-kafka', version: '1.3.3.RELEASE'
|
||||
|
@ -33,3 +33,8 @@ dependencies {
|
|||
latestDepTestLibrary group: 'org.springframework.kafka', name: 'spring-kafka-test', version: '2.2.+'
|
||||
latestDepTestLibrary group: 'org.assertj', name: 'assertj-core', version: '3.+'
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
// TODO run tests both with and without experimental span attributes
|
||||
jvmArgs "-Dotel.instrumentation.kafka.experimental-span-attributes=true"
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
|
|||
import io.opentelemetry.context.Context
|
||||
import io.opentelemetry.context.propagation.TextMapPropagator
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
import java.util.concurrent.TimeUnit
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord
|
||||
|
@ -33,14 +32,6 @@ import org.springframework.kafka.test.utils.KafkaTestUtils
|
|||
import spock.lang.Shared
|
||||
|
||||
class KafkaStreamsTest extends AgentTestRunner {
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfigAndResetInstrumentation {
|
||||
// TODO run tests both with and without experimental span attributes
|
||||
it.setProperty("otel.instrumentation.kafka.experimental-span-attributes", "true")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
static final STREAM_PENDING = "test.pending"
|
||||
static final STREAM_PROCESSED = "test.processed"
|
||||
|
|
|
@ -28,6 +28,15 @@ public class KotlinCoroutinesInstrumentationModule extends InstrumentationModule
|
|||
super("kotlinx-coroutines");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] additionalHelperClassNames() {
|
||||
return new String[] {
|
||||
"io.opentelemetry.extension.kotlin.ContextExtensionsKt",
|
||||
"io.opentelemetry.extension.kotlin.KotlinContextElement",
|
||||
"io.opentelemetry.extension.kotlin.KotlinContextElement$1"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TypeInstrumentation> typeInstrumentations() {
|
||||
return singletonList(new CoroutineScopeLaunchInstrumentation());
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry
|
||||
import io.opentelemetry.api.trace.Tracer
|
||||
import io.opentelemetry.extension.kotlin.asContextElement
|
||||
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
|
@ -26,8 +26,7 @@ import kotlinx.coroutines.withTimeout
|
|||
import kotlinx.coroutines.yield
|
||||
|
||||
class KotlinCoroutineTests(private val dispatcher: CoroutineDispatcher) {
|
||||
// Java8BytecodeBridge is needed in order to support Kotlin which generally targets Java 6 bytecode
|
||||
val tracer: Tracer = Java8BytecodeBridge.getGlobalTracer("io.opentelemetry.auto")
|
||||
val tracer: Tracer = GlobalOpenTelemetry.getTracer("io.opentelemetry.auto")
|
||||
|
||||
fun tracedAcrossChannels() = runTest {
|
||||
|
||||
|
@ -147,6 +146,7 @@ class KotlinCoroutineTests(private val dispatcher: CoroutineDispatcher) {
|
|||
}
|
||||
span.end()
|
||||
}
|
||||
|
||||
suspend fun a2(iter: Long) {
|
||||
var span = tracer.spanBuilder("a2").startSpan()
|
||||
span.setAttribute("iter", iter)
|
||||
|
@ -155,6 +155,7 @@ class KotlinCoroutineTests(private val dispatcher: CoroutineDispatcher) {
|
|||
}
|
||||
span.end()
|
||||
}
|
||||
|
||||
suspend fun b(iter: Long) {
|
||||
var span = tracer.spanBuilder("b").startSpan()
|
||||
span.setAttribute("iter", iter)
|
||||
|
@ -164,6 +165,7 @@ class KotlinCoroutineTests(private val dispatcher: CoroutineDispatcher) {
|
|||
}
|
||||
span.end()
|
||||
}
|
||||
|
||||
suspend fun b2(iter: Long) {
|
||||
var span = tracer.spanBuilder("b2").startSpan()
|
||||
span.setAttribute("iter", iter)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
apply from: "$rootDir/gradle/java.gradle"
|
||||
|
||||
dependencies {
|
||||
testImplementation project(':instrumentation:kubernetes-client-7.0:javaagent')
|
||||
testImplementation group: 'io.kubernetes', name: 'client-java-api', version: '7.0.0'
|
||||
}
|
|
@ -16,5 +16,5 @@ dependencies {
|
|||
|
||||
testImplementation group: 'com.github.kstyrc', name: 'embedded-redis', version: '0.6'
|
||||
testImplementation group: 'io.lettuce', name: 'lettuce-core', version: '5.0.0.RELEASE'
|
||||
testImplementation project(':instrumentation:reactor-3.1:javaagent')
|
||||
testInstrumentation project(':instrumentation:reactor-3.1:javaagent')
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ dependencies {
|
|||
testImplementation group: 'com.github.kstyrc', name: 'embedded-redis', version: '0.6'
|
||||
// Only 5.2+ will have command arguments in the db.statement tag.
|
||||
testLibrary group: 'io.lettuce', name: 'lettuce-core', version: '5.2.0.RELEASE'
|
||||
testImplementation project(':instrumentation:reactor-3.1:javaagent')
|
||||
testInstrumentation project(':instrumentation:reactor-3.1:javaagent')
|
||||
|
||||
latestDepTestLibrary group: 'io.lettuce', name: 'lettuce-core', version: '5.+'
|
||||
}
|
||||
|
|
|
@ -1 +1,7 @@
|
|||
apply from: "$rootDir/gradle/instrumentation.gradle"
|
||||
// not applying $rootDir/gradle/instrumentation.gradle because that brings running tests with agent
|
||||
// infrastructure, and this module only wants to run unit tests
|
||||
|
||||
group = 'io.opentelemetry.javaagent.instrumentation'
|
||||
|
||||
apply from: "$rootDir/gradle/java.gradle"
|
||||
apply from: "$rootDir/gradle/publish.gradle"
|
||||
|
|
|
@ -5,3 +5,7 @@ muzzle {
|
|||
coreJdk = true
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
jvmArgs "-Dotel.instrumentation.methods.include=package.ClassName[method1,method2];MethodTest\$ConfigTracedCallable[call]"
|
||||
}
|
||||
|
|
|
@ -52,6 +52,13 @@ public class MethodInstrumentationModule extends InstrumentationModule {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// the default configuration has empty "otel.instrumentation.methods.include", and so doesn't
|
||||
// generate any TypeInstrumentation for muzzle to analyze
|
||||
@Override
|
||||
protected String[] additionalHelperClassNames() {
|
||||
return new String[] {"io.opentelemetry.javaagent.instrumentation.methods.MethodTracer"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TypeInstrumentation> typeInstrumentations() {
|
||||
return typeInstrumentations;
|
||||
|
|
|
@ -4,18 +4,9 @@
|
|||
*/
|
||||
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
class MethodTest extends AgentTestRunner {
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfigAndResetInstrumentation {
|
||||
it.setProperty("otel.instrumentation.methods.include",
|
||||
"package.ClassName[method1,method2];${ConfigTracedCallable.name}[call]")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
static class ConfigTracedCallable implements Callable<String> {
|
||||
@Override
|
||||
|
|
|
@ -18,5 +18,5 @@ dependencies {
|
|||
testImplementation project(':instrumentation:mongo:mongo-testing')
|
||||
testImplementation group: 'de.flapdoodle.embed', name: 'de.flapdoodle.embed.mongo', version: '1.50.5'
|
||||
|
||||
testImplementation project(':instrumentation:mongo:mongo-3.7:javaagent')
|
||||
testInstrumentation project(':instrumentation:mongo:mongo-3.7:javaagent')
|
||||
}
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
apply from: "$rootDir/gradle/instrumentation.gradle"
|
||||
// not applying $rootDir/gradle/instrumentation.gradle because that brings running tests with agent
|
||||
// infrastructure, and this module only wants to run unit tests
|
||||
|
||||
group = 'io.opentelemetry.javaagent.instrumentation'
|
||||
|
||||
apply from: "$rootDir/gradle/java.gradle"
|
||||
apply from: "$rootDir/gradle/publish.gradle"
|
||||
|
||||
dependencies {
|
||||
library group: 'org.mongodb', name: 'mongo-java-driver', version: '3.1.0'
|
||||
compileOnly project(':instrumentation-api')
|
||||
compileOnly project(':javaagent-api')
|
||||
compileOnly group: 'org.mongodb', name: 'mongo-java-driver', version: '3.1.0'
|
||||
|
||||
testImplementation project(':instrumentation-api')
|
||||
testImplementation project(':javaagent-api')
|
||||
testImplementation group: 'org.mongodb', name: 'mongo-java-driver', version: '3.1.0'
|
||||
}
|
||||
|
|
|
@ -43,7 +43,8 @@ class OkHttp3AsyncTest extends OkHttp3Test {
|
|||
latch.countDown()
|
||||
}
|
||||
})
|
||||
latch.await(20, SECONDS)
|
||||
// need to wait a while for tests of the connection timeout (20 seconds led to failures in CI)
|
||||
latch.await(30, SECONDS)
|
||||
if (exRef.get() != null) {
|
||||
throw exRef.get()
|
||||
}
|
||||
|
|
|
@ -7,5 +7,9 @@ dependencies {
|
|||
// see the comment in opentelemetry-api-1.0.gradle for more details
|
||||
compileOnly project(path: ':opentelemetry-ext-annotations-shaded-for-instrumenting', configuration: 'shadow')
|
||||
|
||||
testImplementation project(path: ':opentelemetry-ext-annotations-shaded-for-instrumenting', configuration: 'shadow')
|
||||
testImplementation deps.opentelemetryExtAnnotations
|
||||
}
|
||||
|
||||
test {
|
||||
jvmArgs "-Dotel.instrumentation.opentelemetry-annotations.exclude-methods=io.opentelemetry.test.annotation.TracedWithSpan[ignored]"
|
||||
}
|
||||
|
|
|
@ -9,21 +9,12 @@ import static io.opentelemetry.api.trace.Span.Kind.SERVER
|
|||
|
||||
import io.opentelemetry.api.trace.Span
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.instrumentation.test.utils.ConfigUtils
|
||||
import io.opentelemetry.test.annotation.TracedWithSpan
|
||||
|
||||
/**
|
||||
* This test verifies that auto instrumentation supports {@link io.opentelemetry.extension.annotations.WithSpan} contrib annotation.
|
||||
*/
|
||||
class WithSpanInstrumentationTest extends AgentTestRunner {
|
||||
static final PREVIOUS_CONFIG = ConfigUtils.updateConfigAndResetInstrumentation {
|
||||
it.setProperty("otel.instrumentation.opentelemetry-annotations.exclude-methods",
|
||||
"${TracedWithSpan.name}[ignored]")
|
||||
}
|
||||
|
||||
def cleanupSpec() {
|
||||
ConfigUtils.setConfig(PREVIOUS_CONFIG)
|
||||
}
|
||||
|
||||
def "should derive automatic name"() {
|
||||
setup:
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
package io.opentelemetry.test.annotation;
|
||||
|
||||
import application.io.opentelemetry.api.trace.Span.Kind;
|
||||
import application.io.opentelemetry.extension.annotations.WithSpan;
|
||||
import io.opentelemetry.api.trace.Span.Kind;
|
||||
import io.opentelemetry.extension.annotations.WithSpan;
|
||||
|
||||
public class TracedWithSpan {
|
||||
|
||||
|
|
|
@ -23,5 +23,13 @@ dependencies {
|
|||
|
||||
// using OpenTelemetry SDK to make sure that instrumentation doesn't cause
|
||||
// OpenTelemetrySdk.getTracerProvider() to throw ClassCastException
|
||||
testImplementation project(path: ':opentelemetry-sdk-shaded-for-instrumenting', configuration: 'shadow')
|
||||
testImplementation deps.opentelemetrySdk
|
||||
|
||||
// @WithSpan annotation is used to generate spans in ContextBridgeTest
|
||||
testImplementation deps.opentelemetryExtAnnotations
|
||||
testInstrumentation project(':instrumentation:opentelemetry-annotations-1.0:javaagent')
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
jvmArgs '-Dotel.trace.annotated.methods.exclude=io.opentelemetry.test.annotation.TracedWithSpan[ignored]'
|
||||
}
|
||||
|
|
|
@ -3,192 +3,150 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import application.io.opentelemetry.api.OpenTelemetry
|
||||
import application.io.opentelemetry.api.baggage.Baggage
|
||||
import application.io.opentelemetry.api.baggage.BaggageEntryMetadata
|
||||
import application.io.opentelemetry.api.trace.Span
|
||||
import application.io.opentelemetry.context.Context
|
||||
import application.io.opentelemetry.context.ContextKey
|
||||
import io.opentelemetry.api.OpenTelemetry
|
||||
import io.opentelemetry.api.baggage.Baggage
|
||||
import io.opentelemetry.api.trace.Span
|
||||
import io.opentelemetry.context.Context
|
||||
import io.opentelemetry.context.ContextKey
|
||||
import io.opentelemetry.extension.annotations.WithSpan
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
class ContextBridgeTest extends AgentTestRunner {
|
||||
|
||||
private static final ContextKey<String> ANIMAL = ContextKey.named("animal")
|
||||
|
||||
private static final io.opentelemetry.context.ContextKey<String> FOOD =
|
||||
io.opentelemetry.context.ContextKey.named("food")
|
||||
private static final io.opentelemetry.context.ContextKey<String> COUNTRY =
|
||||
io.opentelemetry.context.ContextKey.named("country")
|
||||
|
||||
def "agent and application mix"() {
|
||||
expect:
|
||||
def agentContext = io.opentelemetry.context.Context.current().with(COUNTRY, "japan")
|
||||
io.opentelemetry.context.Context.current().get(COUNTRY) == null
|
||||
agentContext.makeCurrent().withCloseable {
|
||||
io.opentelemetry.context.Context.current().get(COUNTRY) == "japan"
|
||||
Context.current().with(ANIMAL, "cat").makeCurrent().withCloseable {
|
||||
Context.current().get(ANIMAL) == "cat"
|
||||
io.opentelemetry.context.Context.current().get(COUNTRY) == "japan"
|
||||
|
||||
def agentContext2 = io.opentelemetry.context.Context.current().with(FOOD, "cheese")
|
||||
io.opentelemetry.context.Context.current().get(FOOD) == null
|
||||
agentContext2.makeCurrent().withCloseable {
|
||||
io.opentelemetry.context.Context.current().get(FOOD) == "cheese"
|
||||
io.opentelemetry.context.Context.current().get(COUNTRY) == "japan"
|
||||
Context.current().get(ANIMAL) == "cat"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The difference between "standard" context interop and our bridge is that with normal interop,
|
||||
// keys are still isolated completely. We have special logic to share the same data for our known
|
||||
// types like span.
|
||||
def "agent and application share span"() {
|
||||
def "agent propagates application's context"() {
|
||||
when:
|
||||
def applicationTracer = OpenTelemetry.getGlobalTracer("test")
|
||||
def agentTracer = io.opentelemetry.api.OpenTelemetry.getGlobalTracer("test")
|
||||
def context = Context.current().with(ANIMAL, "cat")
|
||||
def captured = new AtomicReference<String>()
|
||||
context.makeCurrent().withCloseable {
|
||||
Executors.newSingleThreadExecutor().submit({
|
||||
captured.set(Context.current().get(ANIMAL))
|
||||
}).get()
|
||||
}
|
||||
|
||||
then:
|
||||
!Span.current().spanContext.isValid()
|
||||
!io.opentelemetry.api.trace.Span.current().spanContext.isValid()
|
||||
|
||||
def applicationSpan = applicationTracer.spanBuilder("test1").startSpan()
|
||||
applicationSpan.spanContext.isValid()
|
||||
applicationSpan.makeCurrent().withCloseable {
|
||||
Span.current().spanContext.spanIdAsHexString == applicationSpan.spanContext.spanIdAsHexString
|
||||
io.opentelemetry.api.trace.Span.current().spanContext.spanIdAsHexString == applicationSpan.spanContext.spanIdAsHexString
|
||||
|
||||
def agentSpan = agentTracer.spanBuilder("test2").startSpan()
|
||||
agentSpan.makeCurrent().withCloseable {
|
||||
Span.current().spanContext.spanIdAsHexString == agentSpan.spanContext.spanIdAsHexString
|
||||
Span.current().spanContext.traceIdAsHexString == agentSpan.spanContext.spanIdAsHexString
|
||||
Span.current().spanContext.traceIdAsHexString == applicationSpan.spanContext.spanIdAsHexString
|
||||
io.opentelemetry.api.trace.Span.current().spanContext.spanIdAsHexString == agentSpan.spanContext.spanIdAsHexString
|
||||
io.opentelemetry.api.trace.Span.current().spanContext.traceIdAsHexString == agentSpan.spanContext.traceIdAsHexString
|
||||
io.opentelemetry.api.trace.Span.current().spanContext.traceIdAsHexString == applicationSpan.spanContext.traceIdAsHexString
|
||||
|
||||
def applicationSpan2 = applicationTracer.spanBuilder("test3").startSpan()
|
||||
applicationSpan2.makeCurrent().withCloseable {
|
||||
Span.current().spanContext.spanIdAsHexString == applicationSpan2.spanContext.spanIdAsHexString
|
||||
Span.current().spanContext.traceIdAsHexString == applicationSpan2.spanContext.spanIdAsHexString
|
||||
Span.current().spanContext.traceIdAsHexString == applicationSpan.spanContext.spanIdAsHexString
|
||||
io.opentelemetry.api.trace.Span.current().spanContext.spanIdAsHexString == applicationSpan2.spanContext.spanIdAsHexString
|
||||
io.opentelemetry.api.trace.Span.current().spanContext.traceIdAsHexString == applicationSpan2.spanContext.traceIdAsHexString
|
||||
io.opentelemetry.api.trace.Span.current().spanContext.traceIdAsHexString == applicationSpan.spanContext.traceIdAsHexString
|
||||
}
|
||||
}
|
||||
}
|
||||
captured.get() == "cat"
|
||||
}
|
||||
|
||||
def "agent and application share baggage"() {
|
||||
expect:
|
||||
def applicationBaggage = Baggage.builder()
|
||||
.put("food", "cheese")
|
||||
.put("country", "japan", BaggageEntryMetadata.create("asia"))
|
||||
.build()
|
||||
|
||||
applicationBaggage.makeCurrent().withCloseable {
|
||||
def agentBaggage = io.opentelemetry.api.baggage.Baggage.current()
|
||||
agentBaggage.asMap().with {
|
||||
size() == 2
|
||||
get("food").value == "cheese"
|
||||
get("food").entryMetadata == io.opentelemetry.api.baggage.BaggageEntryMetadata.empty()
|
||||
get("country").value == "japan"
|
||||
get("country").entryMetadata == io.opentelemetry.api.baggage.BaggageEntryMetadata.create("asia")
|
||||
}
|
||||
|
||||
agentBaggage = io.opentelemetry.api.baggage.Baggage.builder()
|
||||
.put("country", "italy", io.opentelemetry.api.baggage.BaggageEntryMetadata.create("europe"))
|
||||
.build()
|
||||
agentBaggage.makeCurrent().withCloseable {
|
||||
def updatedApplicationBaggage = Baggage.current()
|
||||
updatedApplicationBaggage.asMap().with {
|
||||
size() == 2
|
||||
get("food").value == "cheese"
|
||||
get("food").entryMetadata == BaggageEntryMetadata.empty()
|
||||
get("country").value == "italy"
|
||||
get("country").entryMetadata == BaggageEntryMetadata.create("europe")
|
||||
}
|
||||
|
||||
applicationBaggage = applicationBaggage.toBuilder()
|
||||
.put("food", "cabbage")
|
||||
.build()
|
||||
applicationBaggage.makeCurrent().withCloseable {
|
||||
agentBaggage = io.opentelemetry.api.baggage.Baggage.current()
|
||||
agentBaggage.asMap().with {
|
||||
size() == 2
|
||||
get("food").value == "cabbage"
|
||||
get("food").entryMetadata == io.opentelemetry.api.baggage.BaggageEntryMetadata.empty()
|
||||
get("country").value == "japan"
|
||||
get("country").entryMetadata == io.opentelemetry.api.baggage.BaggageEntryMetadata.create("asia")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "agent wraps"() {
|
||||
expect:
|
||||
def agentContext = io.opentelemetry.context.Context.current().with(COUNTRY, "japan")
|
||||
agentContext.makeCurrent().withCloseable {
|
||||
Context.current().with(ANIMAL, "cat").makeCurrent().withCloseable {
|
||||
io.opentelemetry.context.Context.current().get(COUNTRY) == "japan"
|
||||
Context.current().get(ANIMAL) == "cat"
|
||||
|
||||
def agentValue = new AtomicReference<String>()
|
||||
def applicationValue = new AtomicReference<String>()
|
||||
Runnable runnable = {
|
||||
agentValue.set(io.opentelemetry.context.Context.current().get(COUNTRY))
|
||||
applicationValue.set(Context.current().get(ANIMAL))
|
||||
}
|
||||
|
||||
runnable.run()
|
||||
agentValue.get() == null
|
||||
applicationValue.get() == null
|
||||
|
||||
def ctx = io.opentelemetry.context.Context.current()
|
||||
// Simulate another thread by remounting root
|
||||
def "application propagates agent's context"() {
|
||||
when:
|
||||
new Runnable() {
|
||||
@WithSpan("test")
|
||||
@Override
|
||||
void run() {
|
||||
// using @WithSpan above to make the agent generate a context
|
||||
// and then using manual propagation below to verify that context can be propagated by user
|
||||
def context = Context.current()
|
||||
Context.root().makeCurrent().withCloseable {
|
||||
io.opentelemetry.context.Context.root().makeCurrent().withCloseable {
|
||||
ctx.wrap(runnable).run()
|
||||
Span.current().setAttribute("dog", "no")
|
||||
context.makeCurrent().withCloseable {
|
||||
Span.current().setAttribute("cat", "yes")
|
||||
}
|
||||
}
|
||||
}
|
||||
}.run()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
name "test"
|
||||
hasNoParent()
|
||||
attributes {
|
||||
"cat" "yes"
|
||||
}
|
||||
}
|
||||
agentValue.get() == "japan"
|
||||
applicationValue.get() == "cat"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "application wraps"() {
|
||||
expect:
|
||||
def agentContext = io.opentelemetry.context.Context.current().with(COUNTRY, "japan")
|
||||
agentContext.makeCurrent().withCloseable {
|
||||
Context.current().with(ANIMAL, "cat").makeCurrent().withCloseable {
|
||||
io.opentelemetry.context.Context.current().get(COUNTRY) == "japan"
|
||||
Context.current().get(ANIMAL) == "cat"
|
||||
def "agent propagates application's span"() {
|
||||
when:
|
||||
def tracer = OpenTelemetry.getGlobalTracer("test")
|
||||
|
||||
def agentValue = new AtomicReference<String>()
|
||||
def applicationValue = new AtomicReference<String>()
|
||||
Runnable runnable = {
|
||||
agentValue.set(io.opentelemetry.context.Context.current().get(COUNTRY))
|
||||
applicationValue.set(Context.current().get(ANIMAL))
|
||||
def testSpan = tracer.spanBuilder("test").startSpan()
|
||||
testSpan.makeCurrent().withCloseable {
|
||||
Executors.newSingleThreadExecutor().submit({
|
||||
Span.current().setAttribute("cat", "yes")
|
||||
}).get()
|
||||
}
|
||||
testSpan.end()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
name "test"
|
||||
hasNoParent()
|
||||
attributes {
|
||||
"cat" "yes"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
agentValue.get() == null
|
||||
applicationValue.get() == null
|
||||
|
||||
def ctx = Context.current()
|
||||
// Simulate another thread by remounting root
|
||||
def "application propagates agent's span"() {
|
||||
when:
|
||||
new Runnable() {
|
||||
@WithSpan("test")
|
||||
@Override
|
||||
void run() {
|
||||
// using @WithSpan above to make the agent generate a span
|
||||
// and then using manual propagation below to verify that span can be propagated by user
|
||||
def span = Span.current()
|
||||
Context.root().makeCurrent().withCloseable {
|
||||
io.opentelemetry.context.Context.root().makeCurrent().withCloseable {
|
||||
ctx.wrap(runnable).run()
|
||||
Span.current().setAttribute("dog", "no")
|
||||
span.makeCurrent().withCloseable {
|
||||
Span.current().setAttribute("cat", "yes")
|
||||
}
|
||||
}
|
||||
}
|
||||
}.run()
|
||||
|
||||
then:
|
||||
assertTraces(1) {
|
||||
trace(0, 1) {
|
||||
span(0) {
|
||||
name "test"
|
||||
hasNoParent()
|
||||
attributes {
|
||||
"cat" "yes"
|
||||
}
|
||||
}
|
||||
agentValue.get() == "japan"
|
||||
applicationValue.get() == "cat"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "agent propagates application's baggage"() {
|
||||
when:
|
||||
def testBaggage = Baggage.builder().put("cat", "yes").build()
|
||||
def ref = new AtomicReference<Baggage>()
|
||||
def latch = new CountDownLatch(1)
|
||||
testBaggage.makeCurrent().withCloseable {
|
||||
Executors.newSingleThreadExecutor().submit({
|
||||
ref.set(Baggage.current())
|
||||
latch.countDown()
|
||||
}).get()
|
||||
}
|
||||
|
||||
then:
|
||||
latch.await()
|
||||
ref.get().size() == 1
|
||||
ref.get().getEntryValue("cat") == "yes"
|
||||
}
|
||||
|
||||
// TODO (trask)
|
||||
// more tests are needed here, not sure how to implement, probably need to write some test
|
||||
// instrumentation to help test, similar to :testing-common:integration-tests
|
||||
//
|
||||
// * "application propagates agent's baggage"
|
||||
// * "agent uses application's span"
|
||||
// * "application uses agent's span" (this is covered above by "application propagates agent's span")
|
||||
// * "agent uses application's baggage"
|
||||
// * "application uses agent's baggage"
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import application.io.opentelemetry.api.OpenTelemetry
|
||||
import application.io.opentelemetry.api.trace.Span
|
||||
import application.io.opentelemetry.context.Context
|
||||
import io.opentelemetry.api.OpenTelemetry
|
||||
import io.opentelemetry.api.trace.Span
|
||||
import io.opentelemetry.context.Context
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
|
||||
class ContextTest extends AgentTestRunner {
|
||||
|
|
|
@ -8,13 +8,13 @@ import static io.opentelemetry.sdk.metrics.data.MetricData.Type.DOUBLE_SUM
|
|||
import static io.opentelemetry.sdk.metrics.data.MetricData.Type.LONG_GAUGE
|
||||
import static io.opentelemetry.sdk.metrics.data.MetricData.Type.LONG_SUM
|
||||
import static io.opentelemetry.sdk.metrics.data.MetricData.Type.SUMMARY
|
||||
import static java.util.concurrent.TimeUnit.SECONDS
|
||||
|
||||
import application.io.opentelemetry.api.OpenTelemetry
|
||||
import application.io.opentelemetry.api.common.Labels
|
||||
import application.io.opentelemetry.api.metrics.AsynchronousInstrument
|
||||
import com.google.common.base.Stopwatch
|
||||
import io.opentelemetry.api.OpenTelemetry
|
||||
import io.opentelemetry.api.common.Labels
|
||||
import io.opentelemetry.api.metrics.AsynchronousInstrument
|
||||
import io.opentelemetry.instrumentation.test.AgentTestRunner
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData
|
||||
import java.util.function.Consumer
|
||||
|
||||
class MeterTest extends AgentTestRunner {
|
||||
|
@ -42,7 +42,7 @@ class MeterTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
then:
|
||||
def metricData = findMetric(OpenTelemetrySdk.getGlobalMeterProvider().getMetricProducer().collectAllMetrics(), instrumentationName, "test")
|
||||
def metricData = findMetric(instrumentationName, "test")
|
||||
metricData != null
|
||||
metricData.description == "d"
|
||||
metricData.unit == "u"
|
||||
|
@ -52,9 +52,9 @@ class MeterTest extends AgentTestRunner {
|
|||
metricData.points.size() == 1
|
||||
def point = metricData.points.iterator().next()
|
||||
if (bind) {
|
||||
point.labels == io.opentelemetry.api.common.Labels.of("w", "x", "y", "z")
|
||||
point.labels == Labels.of("w", "x", "y", "z")
|
||||
} else {
|
||||
point.labels == io.opentelemetry.api.common.Labels.of("q", "r")
|
||||
point.labels == Labels.of("q", "r")
|
||||
}
|
||||
point.value == expectedValue
|
||||
|
||||
|
@ -93,7 +93,7 @@ class MeterTest extends AgentTestRunner {
|
|||
}
|
||||
|
||||
then:
|
||||
def metricData = findMetric(OpenTelemetrySdk.getGlobalMeterProvider().getMetricProducer().collectAllMetrics(), instrumentationName, "test")
|
||||
def metricData = findMetric(instrumentationName, "test")
|
||||
metricData != null
|
||||
metricData.description == "d"
|
||||
metricData.unit == "u"
|
||||
|
@ -103,9 +103,9 @@ class MeterTest extends AgentTestRunner {
|
|||
metricData.points.size() == 1
|
||||
def point = metricData.points.iterator().next()
|
||||
if (bind) {
|
||||
point.labels == io.opentelemetry.api.common.Labels.of("w", "x", "y", "z")
|
||||
point.labels == Labels.of("w", "x", "y", "z")
|
||||
} else {
|
||||
point.labels == io.opentelemetry.api.common.Labels.of("q", "r")
|
||||
point.labels == Labels.of("q", "r")
|
||||
}
|
||||
|
||||
where:
|
||||
|
@ -172,7 +172,7 @@ class MeterTest extends AgentTestRunner {
|
|||
instrument.build()
|
||||
|
||||
then:
|
||||
def metricData = findMetric(OpenTelemetrySdk.getGlobalMeterProvider().getMetricProducer().collectAllMetrics(), instrumentationName, "test")
|
||||
def metricData = findMetric(instrumentationName, "test")
|
||||
metricData != null
|
||||
metricData.description == "d"
|
||||
metricData.unit == "u"
|
||||
|
@ -181,7 +181,7 @@ class MeterTest extends AgentTestRunner {
|
|||
metricData.instrumentationLibraryInfo.version == "1.2.3"
|
||||
metricData.points.size() == 1
|
||||
def point = metricData.points.iterator().next()
|
||||
point.labels == io.opentelemetry.api.common.Labels.of("q", "r")
|
||||
point.labels == Labels.of("q", "r")
|
||||
if (builderMethod.startsWith("long")) {
|
||||
point.value == 123
|
||||
} else {
|
||||
|
@ -221,10 +221,8 @@ class MeterTest extends AgentTestRunner {
|
|||
.put(doubleMeasure, 6.6)
|
||||
.record()
|
||||
|
||||
def allMetrics = OpenTelemetrySdk.getGlobalMeterProvider().getMetricProducer().collectAllMetrics()
|
||||
|
||||
then:
|
||||
def metricData = findMetric(allMetrics, instrumentationName, "test")
|
||||
def metricData = findMetric(instrumentationName, "test")
|
||||
metricData != null
|
||||
metricData.description == "d"
|
||||
metricData.unit == "u"
|
||||
|
@ -233,10 +231,10 @@ class MeterTest extends AgentTestRunner {
|
|||
metricData.instrumentationLibraryInfo.version == "1.2.3"
|
||||
metricData.points.size() == 1
|
||||
def point = metricData.points.iterator().next()
|
||||
point.labels == io.opentelemetry.api.common.Labels.of("q", "r")
|
||||
point.labels == Labels.of("q", "r")
|
||||
point.value == 11
|
||||
|
||||
def metricData2 = findMetric(allMetrics, instrumentationName, "test2")
|
||||
def metricData2 = findMetric(instrumentationName, "test2")
|
||||
metricData2 != null
|
||||
metricData2.description == "d"
|
||||
metricData2.unit == "u"
|
||||
|
@ -245,15 +243,19 @@ class MeterTest extends AgentTestRunner {
|
|||
metricData2.instrumentationLibraryInfo.version == "1.2.3"
|
||||
metricData2.points.size() == 1
|
||||
def point2 = metricData2.points.iterator().next()
|
||||
point2.labels == io.opentelemetry.api.common.Labels.of("q", "r")
|
||||
point2.labels == Labels.of("q", "r")
|
||||
point2.count == 2
|
||||
point2.sum == 12.1
|
||||
}
|
||||
|
||||
def findMetric(Collection<MetricData> allMetrics, instrumentationName, metricName) {
|
||||
for (def metric : allMetrics) {
|
||||
if (metric.instrumentationLibraryInfo.name == instrumentationName && metric.name == metricName) {
|
||||
return metric
|
||||
def findMetric(instrumentationName, metricName) {
|
||||
Stopwatch stopwatch = Stopwatch.createStarted()
|
||||
while (stopwatch.elapsed(SECONDS) < 10) {
|
||||
def allMetrics = TEST_WRITER.getMetrics()
|
||||
for (def metric : allMetrics) {
|
||||
if (metric.instrumentationLibraryInfo.name == instrumentationName && metric.name == metricName) {
|
||||
return metric
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue