diff --git a/api/all/build.gradle.kts b/api/all/build.gradle.kts
index 4998fd9ddd3..6ade72dfd88 100644
--- a/api/all/build.gradle.kts
+++ b/api/all/build.gradle.kts
@@ -1,6 +1,7 @@
plugins {
id("otel.java-conventions")
id("otel.publish-conventions")
+ id("java-test-fixtures")
id("otel.jmh-conventions")
id("otel.animalsniffer-conventions")
@@ -17,6 +18,10 @@ dependencies {
testImplementation("edu.berkeley.cs.jqf:jqf-fuzz")
testImplementation("com.google.guava:guava-testlib")
+ testFixturesApi(project(":testing-internal"))
+ testFixturesApi("junit:junit")
+ testFixturesApi("org.assertj:assertj-core")
+ testFixturesApi("org.mockito:mockito-core")
}
tasks.test {
diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/IncubatingUtil.java b/api/all/src/main/java/io/opentelemetry/api/internal/IncubatingUtil.java
new file mode 100644
index 00000000000..1ef82d373f2
--- /dev/null
+++ b/api/all/src/main/java/io/opentelemetry/api/internal/IncubatingUtil.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.internal;
+
+import java.lang.reflect.Method;
+
+/**
+ * Incubating utilities.
+ *
+ *
This class is internal and is hence not for public use. Its APIs are unstable and can change
+ * at any time.
+ */
+public class IncubatingUtil {
+ private IncubatingUtil() {}
+
+ @SuppressWarnings("unchecked")
+ public static T incubatingApiIfAvailable(T stableApi, String incubatingClassName) {
+ try {
+ Class> incubatingClass = Class.forName(incubatingClassName);
+ Method getInstance = incubatingClass.getDeclaredMethod("getNoop");
+ return (T) getInstance.invoke(null);
+ } catch (Exception e) {
+ return stableApi;
+ }
+ }
+}
diff --git a/api/all/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java b/api/all/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java
index d00cb310ffc..5bad7eeee51 100644
--- a/api/all/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java
+++ b/api/all/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java
@@ -5,6 +5,7 @@
package io.opentelemetry.api.logs;
+import io.opentelemetry.api.internal.IncubatingUtil;
import javax.annotation.concurrent.ThreadSafe;
/**
@@ -43,6 +44,8 @@ default Logger get(String instrumentationScopeName) {
/** Returns a no-op {@link LoggerProvider} which provides Loggers which do not record or emit. */
static LoggerProvider noop() {
- return DefaultLoggerProvider.getInstance();
+ return IncubatingUtil.incubatingApiIfAvailable(
+ DefaultLoggerProvider.getInstance(),
+ "io.opentelemetry.api.incubator.logs.ExtendedDefaultLoggerProvider");
}
}
diff --git a/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java b/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java
index 6d1a6de3d48..3ea78ec2d34 100644
--- a/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java
+++ b/api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java
@@ -5,6 +5,8 @@
package io.opentelemetry.api.metrics;
+import io.opentelemetry.api.internal.IncubatingUtil;
+
/** A {@link MeterProvider} that does nothing. */
class DefaultMeterProvider implements MeterProvider {
@Override
@@ -12,7 +14,10 @@ public MeterBuilder meterBuilder(String instrumentationScopeName) {
return BUILDER_INSTANCE;
}
- private static final DefaultMeterProvider INSTANCE = new DefaultMeterProvider();
+ private static final MeterProvider INSTANCE =
+ IncubatingUtil.incubatingApiIfAvailable(
+ new DefaultMeterProvider(),
+ "io.opentelemetry.api.incubator.metrics.ExtendedDefaultMeterProvider");
private static final MeterBuilder BUILDER_INSTANCE = new NoopMeterBuilder();
static MeterProvider getInstance() {
diff --git a/api/all/src/main/java/io/opentelemetry/api/trace/DefaultTracerProvider.java b/api/all/src/main/java/io/opentelemetry/api/trace/DefaultTracerProvider.java
index 97ddbe0c7b8..9bef6cf9928 100644
--- a/api/all/src/main/java/io/opentelemetry/api/trace/DefaultTracerProvider.java
+++ b/api/all/src/main/java/io/opentelemetry/api/trace/DefaultTracerProvider.java
@@ -5,12 +5,16 @@
package io.opentelemetry.api.trace;
+import io.opentelemetry.api.internal.IncubatingUtil;
import javax.annotation.concurrent.ThreadSafe;
@ThreadSafe
class DefaultTracerProvider implements TracerProvider {
- private static final TracerProvider INSTANCE = new DefaultTracerProvider();
+ private static final TracerProvider INSTANCE =
+ IncubatingUtil.incubatingApiIfAvailable(
+ new DefaultTracerProvider(),
+ "io.opentelemetry.api.incubator.trace.ExtendedDefaultTracerProvider");
static TracerProvider getInstance() {
return INSTANCE;
diff --git a/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java b/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java
index 42a4cd31476..c3754a6df3b 100644
--- a/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java
+++ b/api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java
@@ -5,100 +5,24 @@
package io.opentelemetry.api;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.mock;
-
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.api.trace.TracerProvider;
-import io.opentelemetry.context.propagation.ContextPropagators;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-class OpenTelemetryTest {
-
- @BeforeAll
- static void beforeClass() {
- GlobalOpenTelemetry.resetForTest();
- }
-
- @AfterEach
- void after() {
- GlobalOpenTelemetry.resetForTest();
- }
-
- @Test
- void testDefault() {
- assertThat(OpenTelemetry.noop().getTracerProvider()).isSameAs(TracerProvider.noop());
- assertThat(OpenTelemetry.noop().getPropagators()).isSameAs(ContextPropagators.noop());
- assertThat(OpenTelemetry.noop().getMeterProvider()).isSameAs(MeterProvider.noop());
- assertThat(OpenTelemetry.noop().getLogsBridge()).isSameAs(LoggerProvider.noop());
- }
- @Test
- void propagating() {
- ContextPropagators contextPropagators = mock(ContextPropagators.class);
- OpenTelemetry openTelemetry = OpenTelemetry.propagating(contextPropagators);
-
- assertThat(openTelemetry.getTracerProvider()).isSameAs(TracerProvider.noop());
- assertThat(openTelemetry.getMeterProvider()).isSameAs(MeterProvider.noop());
- assertThat(openTelemetry.getLogsBridge()).isSameAs(LoggerProvider.noop());
- assertThat(openTelemetry.getPropagators()).isSameAs(contextPropagators);
- }
-
- @Test
- void testGlobalBeforeSet() {
- assertThat(GlobalOpenTelemetry.getTracerProvider()).isSameAs(TracerProvider.noop());
- assertThat(GlobalOpenTelemetry.getTracerProvider())
- .isSameAs(GlobalOpenTelemetry.getTracerProvider());
- assertThat(GlobalOpenTelemetry.getPropagators()).isSameAs(GlobalOpenTelemetry.getPropagators());
- }
-
- @Test
- void independentNonGlobalPropagators() {
- ContextPropagators propagators1 = mock(ContextPropagators.class);
- OpenTelemetry otel1 = OpenTelemetry.propagating(propagators1);
- ContextPropagators propagators2 = mock(ContextPropagators.class);
- OpenTelemetry otel2 = OpenTelemetry.propagating(propagators2);
-
- assertThat(otel1.getPropagators()).isSameAs(propagators1);
- assertThat(otel2.getPropagators()).isSameAs(propagators2);
- }
-
- @Test
- void setThenSet() {
- setOpenTelemetry();
- assertThatThrownBy(() -> GlobalOpenTelemetry.set(OpenTelemetry.noop()))
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("GlobalOpenTelemetry.set has already been called")
- .hasStackTraceContaining("setOpenTelemetry");
- }
-
- @Test
- void getThenSet() {
- assertThat(getOpenTelemetry()).isInstanceOf(DefaultOpenTelemetry.class);
- assertThatThrownBy(() -> GlobalOpenTelemetry.set(OpenTelemetry.noop()))
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("GlobalOpenTelemetry.set has already been called")
- .hasStackTraceContaining("getOpenTelemetry");
- }
+class OpenTelemetryTest extends AbstractOpenTelemetryTest {
- @Test
- void toString_noop_Valid() {
- assertThat(OpenTelemetry.noop().toString())
- .isEqualTo(
- "DefaultOpenTelemetry{"
- + "propagators=DefaultContextPropagators{textMapPropagator=NoopTextMapPropagator}"
- + "}");
+ @Override
+ protected TracerProvider getTracerProvider() {
+ return TracerProvider.noop();
}
- private static void setOpenTelemetry() {
- GlobalOpenTelemetry.set(OpenTelemetry.noop());
+ @Override
+ protected MeterProvider getMeterProvider() {
+ return MeterProvider.noop();
}
- private static OpenTelemetry getOpenTelemetry() {
- return GlobalOpenTelemetry.get();
+ @Override
+ protected LoggerProvider getLoggerProvider() {
+ return LoggerProvider.noop();
}
}
diff --git a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerProviderTest.java b/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerProviderTest.java
deleted file mode 100644
index 81a8bec1f84..00000000000
--- a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerProviderTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.api.logs;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-
-import org.junit.jupiter.api.Test;
-
-class DefaultLoggerProviderTest {
-
- @Test
- void noopLoggerProvider_doesNotThrow() {
- LoggerProvider provider = LoggerProvider.noop();
-
- assertThat(provider).isSameAs(DefaultLoggerProvider.getInstance());
- assertThatCode(() -> provider.get("scope-name")).doesNotThrowAnyException();
- assertThatCode(
- () ->
- provider
- .loggerBuilder("scope-name")
- .setInstrumentationVersion("1.0")
- .setSchemaUrl("http://schema.com")
- .build())
- .doesNotThrowAnyException();
-
- assertThatCode(() -> provider.loggerBuilder("scope-name").build().logRecordBuilder())
- .doesNotThrowAnyException();
- }
-}
diff --git a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java b/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java
index ffe68f37e95..436baee524c 100644
--- a/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java
+++ b/api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java
@@ -5,36 +5,15 @@
package io.opentelemetry.api.logs;
-import static org.assertj.core.api.Assertions.assertThatCode;
+class DefaultLoggerTest extends AbstractDefaultLoggerTest {
-import io.opentelemetry.api.common.AttributeKey;
-import io.opentelemetry.api.common.Attributes;
-import io.opentelemetry.api.common.Value;
-import io.opentelemetry.context.Context;
-import java.time.Instant;
-import java.util.concurrent.TimeUnit;
-import org.junit.jupiter.api.Test;
-
-class DefaultLoggerTest {
+ @Override
+ protected LoggerProvider getLoggerProvider() {
+ return DefaultLoggerProvider.getInstance();
+ }
- @Test
- void buildAndEmit() {
- assertThatCode(
- () ->
- DefaultLogger.getInstance()
- .logRecordBuilder()
- .setTimestamp(100, TimeUnit.SECONDS)
- .setTimestamp(Instant.now())
- .setObservedTimestamp(100, TimeUnit.SECONDS)
- .setObservedTimestamp(Instant.now())
- .setContext(Context.root())
- .setSeverity(Severity.DEBUG)
- .setSeverityText("debug")
- .setBody("body")
- .setBody(Value.of("body"))
- .setAttribute(AttributeKey.stringKey("key1"), "value1")
- .setAllAttributes(Attributes.builder().put("key2", "value2").build())
- .emit())
- .doesNotThrowAnyException();
+ @Override
+ protected Logger getLogger() {
+ return DefaultLogger.getInstance();
}
}
diff --git a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterProviderTest.java b/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterProviderTest.java
deleted file mode 100644
index 786d0a68a6e..00000000000
--- a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterProviderTest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.api.metrics;
-
-import org.junit.jupiter.api.Test;
-
-public class DefaultMeterProviderTest {
- @Test
- void noopMeterProvider_getDoesNotThrow() {
- MeterProvider provider = MeterProvider.noop();
- provider.get("user-instrumentation");
- }
-
- @Test
- void noopMeterProvider_builderDoesNotThrow() {
- MeterProvider provider = MeterProvider.noop();
- provider.meterBuilder("user-instrumentation").build();
- provider.meterBuilder("advanced-instrumetnation").setInstrumentationVersion("1.0").build();
- provider.meterBuilder("schema-instrumentation").setSchemaUrl("myschema://url").build();
- provider
- .meterBuilder("schema-instrumentation")
- .setInstrumentationVersion("1.0")
- .setSchemaUrl("myschema://url")
- .build();
- }
-}
diff --git a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java b/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java
index fd9884bdad7..1b012be1d55 100644
--- a/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java
+++ b/api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterTest.java
@@ -5,199 +5,15 @@
package io.opentelemetry.api.metrics;
-import static io.opentelemetry.api.common.AttributeKey.stringKey;
+public class DefaultMeterTest extends AbstractDefaultMeterTest {
-import io.opentelemetry.api.common.Attributes;
-import io.opentelemetry.context.Context;
-import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
-import org.junit.jupiter.api.Test;
-
-@SuppressLogger()
-public class DefaultMeterTest {
- private static final Meter METER = DefaultMeter.getInstance();
-
- @Test
- void noopLongCounter_doesNotThrow() {
- LongCounter counter =
- METER.counterBuilder("size").setDescription("The size I'm measuring").setUnit("1").build();
- counter.add(1);
- counter.add(1, Attributes.of(stringKey("thing"), "car"));
- counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current());
- }
-
- @Test
- void noopDoubleCounter_doesNotThrow() {
- DoubleCounter counter =
- METER
- .counterBuilder("size")
- .ofDoubles()
- .setDescription("The size I'm measuring")
- .setUnit("1")
- .build();
- counter.add(1.2);
- counter.add(2.5, Attributes.of(stringKey("thing"), "car"));
- counter.add(2.5, Attributes.of(stringKey("thing"), "car"), Context.current());
- }
-
- @Test
- void noopLongUpDownCounter_doesNotThrow() {
- LongUpDownCounter counter =
- METER
- .upDownCounterBuilder("size")
- .setDescription("The size I'm measuring")
- .setUnit("1")
- .build();
- counter.add(-1);
- counter.add(1, Attributes.of(stringKey("thing"), "car"));
- counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current());
- }
-
- @Test
- void noopDoubleUpDownCounter_doesNotThrow() {
- DoubleUpDownCounter counter =
- METER
- .upDownCounterBuilder("size")
- .ofDoubles()
- .setDescription("The size I'm measuring")
- .setUnit("1")
- .build();
- counter.add(-2e4);
- counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car"));
- counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current());
- }
-
- @Test
- void noopLongHistogram_doesNotThrow() {
- LongHistogram histogram =
- METER
- .histogramBuilder("size")
- .ofLongs()
- .setDescription("The size I'm measuring")
- .setUnit("1")
- .build();
- histogram.record(-1);
- histogram.record(1, Attributes.of(stringKey("thing"), "car"));
- histogram.record(1, Attributes.of(stringKey("thing"), "car"), Context.current());
- }
-
- @Test
- void noopDoubleHistogram_doesNotThrow() {
- DoubleHistogram histogram =
- METER
- .histogramBuilder("size")
- .setDescription("The size I'm measuring")
- .setUnit("1")
- .build();
- histogram.record(-2e4);
- histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car"));
- histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current());
- }
-
- @Test
- void noopLongGauage_doesNotThrow() {
- LongGauge gauge =
- METER
- .gaugeBuilder("temperature")
- .ofLongs()
- .setDescription("The current temperature")
- .setUnit("C")
- .build();
- gauge.set(1);
- gauge.set(2, Attributes.of(stringKey("thing"), "engine"));
- gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current());
- }
-
- @Test
- void noopObservableLongGauage_doesNotThrow() {
- METER
- .gaugeBuilder("temperature")
- .ofLongs()
- .setDescription("The current temperature")
- .setUnit("C")
- .buildWithCallback(
- m -> {
- m.record(1);
- m.record(2, Attributes.of(stringKey("thing"), "engine"));
- });
- }
-
- @Test
- void noopDoubleGauage_doesNotThrow() {
- DoubleGauge gauge =
- METER
- .gaugeBuilder("temperature")
- .setDescription("The current temperature")
- .setUnit("C")
- .build();
- gauge.set(1);
- gauge.set(2, Attributes.of(stringKey("thing"), "engine"));
- gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current());
- }
-
- @Test
- void noopObservableDoubleGauage_doesNotThrow() {
- METER
- .gaugeBuilder("temperature")
- .setDescription("The current temperature")
- .setUnit("C")
- .buildWithCallback(
- m -> {
- m.record(1.0e1);
- m.record(-27.4, Attributes.of(stringKey("thing"), "engine"));
- });
- }
-
- @Test
- void noopObservableLongCounter_doesNotThrow() {
- METER
- .counterBuilder("temperature")
- .setDescription("The current temperature")
- .setUnit("C")
- .buildWithCallback(
- m -> {
- m.record(1);
- m.record(2, Attributes.of(stringKey("thing"), "engine"));
- });
- }
-
- @Test
- void noopObservableDoubleCounter_doesNotThrow() {
- METER
- .counterBuilder("temperature")
- .ofDoubles()
- .setDescription("The current temperature")
- .setUnit("C")
- .buildWithCallback(
- m -> {
- m.record(1.0e1);
- m.record(-27.4, Attributes.of(stringKey("thing"), "engine"));
- });
- }
-
- @Test
- void noopObservableLongUpDownCounter_doesNotThrow() {
- METER
- .upDownCounterBuilder("temperature")
- .setDescription("The current temperature")
- .setUnit("C")
- .buildWithCallback(
- m -> {
- m.record(1);
- m.record(2, Attributes.of(stringKey("thing"), "engine"));
- });
+ @Override
+ protected Meter getMeter() {
+ return DefaultMeter.getInstance();
}
- @Test
- void noopObservableDoubleUpDownCounter_doesNotThrow() {
- METER
- .upDownCounterBuilder("temperature")
- .ofDoubles()
- .setDescription("The current temperature")
- .setUnit("C")
- .buildWithCallback(
- m -> {
- m.record(1.0e1);
- m.record(-27.4, Attributes.of(stringKey("thing"), "engine"));
- });
+ @Override
+ protected MeterProvider getMeterProvider() {
+ return DefaultMeterProvider.getInstance();
}
}
diff --git a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerProviderTest.java b/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerProviderTest.java
deleted file mode 100644
index 72a98f29f59..00000000000
--- a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerProviderTest.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.api.trace;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import org.junit.jupiter.api.Test;
-
-class DefaultTracerProviderTest {
-
- @Test
- void returnsDefaultTracer() {
- assertThat(TracerProvider.noop().get("test")).isInstanceOf(DefaultTracer.class);
- assertThat(TracerProvider.noop().get("test", "1.0")).isInstanceOf(DefaultTracer.class);
- }
-}
diff --git a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java b/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java
index dc364e96457..f0f577d9946 100644
--- a/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java
+++ b/api/all/src/test/java/io/opentelemetry/api/trace/DefaultTracerTest.java
@@ -5,89 +5,15 @@
package io.opentelemetry.api.trace;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
+class DefaultTracerTest extends AbstractDefaultTracerTest {
-import io.opentelemetry.api.common.Attributes;
-import io.opentelemetry.context.Context;
-import org.junit.jupiter.api.Test;
-
-/** Unit tests for {@link DefaultTracer}. */
-// Need to suppress warnings for MustBeClosed because Android 14 does not support
-// try-with-resources.
-@SuppressWarnings("MustBeClosedChecker")
-class DefaultTracerTest {
- private static final Tracer defaultTracer = DefaultTracer.getInstance();
- private static final String SPAN_NAME = "MySpanName";
- private static final SpanContext spanContext =
- SpanContext.create(
- "00000000000000000000000000000061",
- "0000000000000061",
- TraceFlags.getDefault(),
- TraceState.getDefault());
-
- @Test
- void defaultSpanBuilderWithName() {
- assertThat(defaultTracer.spanBuilder(SPAN_NAME).startSpan().getSpanContext().isValid())
- .isFalse();
- }
-
- @Test
- void testSpanContextPropagationExplicitParent() {
- Span span =
- defaultTracer
- .spanBuilder(SPAN_NAME)
- .setParent(Context.root().with(Span.wrap(spanContext)))
- .startSpan();
- assertThat(span.getSpanContext()).isSameAs(spanContext);
- }
-
- @Test
- void testSpanContextPropagation() {
- Span parent = Span.wrap(spanContext);
-
- Span span =
- defaultTracer.spanBuilder(SPAN_NAME).setParent(Context.root().with(parent)).startSpan();
- assertThat(span.getSpanContext()).isSameAs(spanContext);
- }
-
- @Test
- void noSpanContextMakesInvalidSpans() {
- Span span = defaultTracer.spanBuilder(SPAN_NAME).startSpan();
- assertThat(span.getSpanContext()).isSameAs(SpanContext.getInvalid());
- }
-
- @Test
- void testSpanContextPropagation_fromContext() {
- Context context = Context.current().with(Span.wrap(spanContext));
-
- Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).startSpan();
- assertThat(span.getSpanContext()).isSameAs(spanContext);
- }
-
- @Test
- void testSpanContextPropagation_fromContextAfterNoParent() {
- Context context = Context.current().with(Span.wrap(spanContext));
-
- Span span = defaultTracer.spanBuilder(SPAN_NAME).setNoParent().setParent(context).startSpan();
- assertThat(span.getSpanContext()).isSameAs(spanContext);
- }
-
- @Test
- void testSpanContextPropagation_fromContextThenNoParent() {
- Context context = Context.current().with(Span.wrap(spanContext));
-
- Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).setNoParent().startSpan();
- assertThat(span.getSpanContext()).isEqualTo(SpanContext.getInvalid());
+ @Override
+ public Tracer getTracer() {
+ return DefaultTracer.getInstance();
}
- @Test
- void addLink() {
- Span span = Span.fromContext(Context.root());
- assertThatCode(() -> span.addLink(null)).doesNotThrowAnyException();
- assertThatCode(() -> span.addLink(SpanContext.getInvalid())).doesNotThrowAnyException();
- assertThatCode(() -> span.addLink(null, null)).doesNotThrowAnyException();
- assertThatCode(() -> span.addLink(SpanContext.getInvalid(), Attributes.empty()))
- .doesNotThrowAnyException();
+ @Override
+ public TracerProvider getTracerProvider() {
+ return DefaultTracerProvider.getInstance();
}
}
diff --git a/api/all/src/test/java/io/opentelemetry/api/trace/SpanBuilderTest.java b/api/all/src/test/java/io/opentelemetry/api/trace/SpanBuilderTest.java
deleted file mode 100644
index a7ed2dc27cb..00000000000
--- a/api/all/src/test/java/io/opentelemetry/api/trace/SpanBuilderTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.api.trace;
-
-import static io.opentelemetry.api.common.AttributeKey.stringKey;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-
-import io.opentelemetry.api.common.AttributeKey;
-import io.opentelemetry.api.common.Attributes;
-import io.opentelemetry.context.Context;
-import java.time.Instant;
-import java.util.concurrent.TimeUnit;
-import org.junit.jupiter.api.Test;
-
-/** Unit tests for {@link SpanBuilder}. */
-class SpanBuilderTest {
- private final Tracer tracer = DefaultTracer.getInstance();
-
- @Test
- void doNotCrash_NoopImplementation() {
- assertThatCode(
- () -> {
- SpanBuilder spanBuilder = tracer.spanBuilder(null);
- spanBuilder.setSpanKind(null);
- spanBuilder.setParent(null);
- spanBuilder.setNoParent();
- spanBuilder.addLink(null);
- spanBuilder.addLink(null, Attributes.empty());
- spanBuilder.addLink(SpanContext.getInvalid(), null);
- spanBuilder.setAttribute((String) null, "foo");
- spanBuilder.setAttribute("foo", null);
- spanBuilder.setAttribute(null, 0L);
- spanBuilder.setAttribute(null, 0.0);
- spanBuilder.setAttribute(null, false);
- spanBuilder.setAttribute((AttributeKey) null, "foo");
- spanBuilder.setAttribute(stringKey(null), "foo");
- spanBuilder.setAttribute(stringKey(""), "foo");
- spanBuilder.setAttribute(stringKey("foo"), null);
- spanBuilder.setStartTimestamp(-1, TimeUnit.MILLISECONDS);
- spanBuilder.setStartTimestamp(1, null);
- spanBuilder.setParent(Context.root().with(Span.wrap(null)));
- spanBuilder.setParent(Context.root());
- spanBuilder.setNoParent();
- spanBuilder.addLink(Span.getInvalid().getSpanContext());
- spanBuilder.addLink(Span.getInvalid().getSpanContext(), Attributes.empty());
- spanBuilder.setAttribute("key", "value");
- spanBuilder.setAttribute("key", 12345L);
- spanBuilder.setAttribute("key", .12345);
- spanBuilder.setAttribute("key", true);
- spanBuilder.setAttribute(stringKey("key"), "value");
- spanBuilder.setAllAttributes(Attributes.of(stringKey("key"), "value"));
- spanBuilder.setAllAttributes(Attributes.empty());
- spanBuilder.setAllAttributes(null);
- spanBuilder.setStartTimestamp(12345L, TimeUnit.NANOSECONDS);
- spanBuilder.setStartTimestamp(Instant.EPOCH);
- spanBuilder.setStartTimestamp(null);
- assertThat(spanBuilder.startSpan().getSpanContext().isValid()).isFalse();
- })
- .doesNotThrowAnyException();
- }
-}
diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/AbstractOpenTelemetryTest.java b/api/all/src/testFixtures/java/io/opentelemetry/api/AbstractOpenTelemetryTest.java
new file mode 100644
index 00000000000..6ba27d89760
--- /dev/null
+++ b/api/all/src/testFixtures/java/io/opentelemetry/api/AbstractOpenTelemetryTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import io.opentelemetry.api.logs.LoggerProvider;
+import io.opentelemetry.api.metrics.MeterProvider;
+import io.opentelemetry.api.trace.TracerProvider;
+import io.opentelemetry.context.propagation.ContextPropagators;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+/** Unit tests for {@link OpenTelemetry}. */
+public abstract class AbstractOpenTelemetryTest {
+ @BeforeAll
+ public static void beforeClass() {
+ GlobalOpenTelemetry.resetForTest();
+ }
+
+ private void setOpenTelemetry() {
+ GlobalOpenTelemetry.set(getOpenTelemetry());
+ }
+
+ private static OpenTelemetry getGlobalOpenTelemetry() {
+ return GlobalOpenTelemetry.get();
+ }
+
+ @AfterEach
+ public void after() {
+ GlobalOpenTelemetry.resetForTest();
+ }
+
+ @Test
+ void testDefault() {
+ assertThat(getOpenTelemetry().getTracerProvider()).isSameAs(getTracerProvider());
+ assertThat(getOpenTelemetry().getPropagators()).isSameAs(ContextPropagators.noop());
+ assertThat(getOpenTelemetry().getMeterProvider()).isSameAs(getMeterProvider());
+ assertThat(getOpenTelemetry().getLogsBridge()).isSameAs(getLoggerProvider());
+ }
+
+ protected abstract TracerProvider getTracerProvider();
+
+ protected OpenTelemetry getOpenTelemetry() {
+ return OpenTelemetry.noop();
+ }
+
+ protected abstract MeterProvider getMeterProvider();
+
+ protected abstract LoggerProvider getLoggerProvider();
+
+ @Test
+ void propagating() {
+ ContextPropagators contextPropagators = Mockito.mock(ContextPropagators.class);
+ OpenTelemetry openTelemetry = OpenTelemetry.propagating(contextPropagators);
+
+ assertThat(openTelemetry.getTracerProvider()).isSameAs(getTracerProvider());
+ assertThat(openTelemetry.getMeterProvider()).isSameAs(getMeterProvider());
+ assertThat(openTelemetry.getLogsBridge()).isSameAs(getLoggerProvider());
+ assertThat(openTelemetry.getPropagators()).isSameAs(contextPropagators);
+ }
+
+ @Test
+ void testGlobalBeforeSet() {
+ assertThat(GlobalOpenTelemetry.getTracerProvider()).isSameAs(getTracerProvider());
+ assertThat(GlobalOpenTelemetry.getTracerProvider())
+ .isSameAs(GlobalOpenTelemetry.getTracerProvider());
+ assertThat(GlobalOpenTelemetry.getPropagators()).isSameAs(GlobalOpenTelemetry.getPropagators());
+ }
+
+ @Test
+ void independentNonGlobalPropagators() {
+ ContextPropagators propagators1 = Mockito.mock(ContextPropagators.class);
+ OpenTelemetry otel1 = OpenTelemetry.propagating(propagators1);
+ ContextPropagators propagators2 = Mockito.mock(ContextPropagators.class);
+ OpenTelemetry otel2 = OpenTelemetry.propagating(propagators2);
+
+ assertThat(otel1.getPropagators()).isSameAs(propagators1);
+ assertThat(otel2.getPropagators()).isSameAs(propagators2);
+ }
+
+ @Test
+ void setThenSet() {
+ setOpenTelemetry();
+ assertThatThrownBy(() -> GlobalOpenTelemetry.set(getOpenTelemetry()))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("GlobalOpenTelemetry.set has already been called")
+ .hasStackTraceContaining("setOpenTelemetry");
+ }
+
+ @Test
+ void getThenSet() {
+ assertThat(getGlobalOpenTelemetry()).isInstanceOf(DefaultOpenTelemetry.class);
+ assertThatThrownBy(() -> GlobalOpenTelemetry.set(getOpenTelemetry()))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("GlobalOpenTelemetry.set has already been called")
+ .hasStackTraceContaining("getGlobalOpenTelemetry");
+ }
+
+ @Test
+ void toString_noop_Valid() {
+ assertThat(getOpenTelemetry().toString())
+ .isEqualTo(
+ "DefaultOpenTelemetry{"
+ + "propagators=DefaultContextPropagators{textMapPropagator=NoopTextMapPropagator}"
+ + "}");
+ }
+}
diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/logs/AbstractDefaultLoggerTest.java b/api/all/src/testFixtures/java/io/opentelemetry/api/logs/AbstractDefaultLoggerTest.java
new file mode 100644
index 00000000000..88ecb74809a
--- /dev/null
+++ b/api/all/src/testFixtures/java/io/opentelemetry/api/logs/AbstractDefaultLoggerTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.logs;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.common.Value;
+import io.opentelemetry.context.Context;
+import java.time.Instant;
+import java.util.concurrent.TimeUnit;
+import org.junit.jupiter.api.Test;
+
+/** Unit tests for {@link DefaultLogger}. */
+public abstract class AbstractDefaultLoggerTest {
+
+ protected abstract LoggerProvider getLoggerProvider();
+
+ protected abstract Logger getLogger();
+
+ @Test
+ void noopLoggerProvider_doesNotThrow() {
+ LoggerProvider provider = LoggerProvider.noop();
+
+ assertThat(provider).isSameAs(getLoggerProvider());
+ assertThatCode(() -> provider.get("scope-name")).doesNotThrowAnyException();
+ assertThatCode(
+ () ->
+ provider
+ .loggerBuilder("scope-name")
+ .setInstrumentationVersion("1.0")
+ .setSchemaUrl("http://schema.com")
+ .build())
+ .doesNotThrowAnyException();
+
+ assertThatCode(() -> provider.loggerBuilder("scope-name").build().logRecordBuilder())
+ .doesNotThrowAnyException();
+ }
+
+ @Test
+ void buildAndEmit() {
+ assertThatCode(
+ () ->
+ getLogger()
+ .logRecordBuilder()
+ .setTimestamp(100, TimeUnit.SECONDS)
+ .setTimestamp(Instant.now())
+ .setObservedTimestamp(100, TimeUnit.SECONDS)
+ .setObservedTimestamp(Instant.now())
+ .setContext(Context.root())
+ .setSeverity(Severity.DEBUG)
+ .setSeverityText("debug")
+ .setBody("body")
+ .setBody(Value.of("body"))
+ .setAttribute(AttributeKey.stringKey("key1"), "value1")
+ .setAllAttributes(Attributes.builder().put("key2", "value2").build())
+ .emit())
+ .doesNotThrowAnyException();
+ }
+}
diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/metrics/AbstractDefaultMeterTest.java b/api/all/src/testFixtures/java/io/opentelemetry/api/metrics/AbstractDefaultMeterTest.java
new file mode 100644
index 00000000000..b64c0929803
--- /dev/null
+++ b/api/all/src/testFixtures/java/io/opentelemetry/api/metrics/AbstractDefaultMeterTest.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.metrics;
+
+import static io.opentelemetry.api.common.AttributeKey.stringKey;
+
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
+import org.junit.jupiter.api.Test;
+
+/** Unit tests for {@link DefaultMeter}. */
+@SuppressLogger()
+public abstract class AbstractDefaultMeterTest {
+ private final Meter meter = getMeter();
+
+ protected abstract Meter getMeter();
+
+ protected abstract MeterProvider getMeterProvider();
+
+ @Test
+ void noopMeterProvider_getDoesNotThrow() {
+ MeterProvider provider = getMeterProvider();
+ provider.get("user-instrumentation");
+ }
+
+ @Test
+ void noopMeterProvider_builderDoesNotThrow() {
+ MeterProvider provider = getMeterProvider();
+ provider.meterBuilder("user-instrumentation").build();
+ provider.meterBuilder("advanced-instrumetnation").setInstrumentationVersion("1.0").build();
+ provider.meterBuilder("schema-instrumentation").setSchemaUrl("myschema://url").build();
+ provider
+ .meterBuilder("schema-instrumentation")
+ .setInstrumentationVersion("1.0")
+ .setSchemaUrl("myschema://url")
+ .build();
+ }
+
+ @Test
+ void noopLongCounter_doesNotThrow() {
+ LongCounter counter =
+ meter.counterBuilder("size").setDescription("The size I'm measuring").setUnit("1").build();
+ counter.add(1);
+ counter.add(1, Attributes.of(stringKey("thing"), "car"));
+ counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current());
+ }
+
+ @Test
+ void noopDoubleCounter_doesNotThrow() {
+ DoubleCounter counter =
+ meter
+ .counterBuilder("size")
+ .ofDoubles()
+ .setDescription("The size I'm measuring")
+ .setUnit("1")
+ .build();
+ counter.add(1.2);
+ counter.add(2.5, Attributes.of(stringKey("thing"), "car"));
+ counter.add(2.5, Attributes.of(stringKey("thing"), "car"), Context.current());
+ }
+
+ @Test
+ void noopLongUpDownCounter_doesNotThrow() {
+ LongUpDownCounter counter =
+ meter
+ .upDownCounterBuilder("size")
+ .setDescription("The size I'm measuring")
+ .setUnit("1")
+ .build();
+ counter.add(-1);
+ counter.add(1, Attributes.of(stringKey("thing"), "car"));
+ counter.add(1, Attributes.of(stringKey("thing"), "car"), Context.current());
+ }
+
+ @Test
+ void noopDoubleUpDownCounter_doesNotThrow() {
+ DoubleUpDownCounter counter =
+ meter
+ .upDownCounterBuilder("size")
+ .ofDoubles()
+ .setDescription("The size I'm measuring")
+ .setUnit("1")
+ .build();
+ counter.add(-2e4);
+ counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car"));
+ counter.add(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current());
+ }
+
+ @Test
+ void noopLongHistogram_doesNotThrow() {
+ LongHistogram histogram =
+ meter
+ .histogramBuilder("size")
+ .ofLongs()
+ .setDescription("The size I'm measuring")
+ .setUnit("1")
+ .build();
+ histogram.record(-1);
+ histogram.record(1, Attributes.of(stringKey("thing"), "car"));
+ histogram.record(1, Attributes.of(stringKey("thing"), "car"), Context.current());
+ }
+
+ @Test
+ void noopDoubleHistogram_doesNotThrow() {
+ DoubleHistogram histogram =
+ meter
+ .histogramBuilder("size")
+ .setDescription("The size I'm measuring")
+ .setUnit("1")
+ .build();
+ histogram.record(-2e4);
+ histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car"));
+ histogram.record(1.0e-1, Attributes.of(stringKey("thing"), "car"), Context.current());
+ }
+
+ @Test
+ void noopLongGauage_doesNotThrow() {
+ LongGauge gauge =
+ meter
+ .gaugeBuilder("temperature")
+ .ofLongs()
+ .setDescription("The current temperature")
+ .setUnit("C")
+ .build();
+ gauge.set(1);
+ gauge.set(2, Attributes.of(stringKey("thing"), "engine"));
+ gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current());
+
+ ObservableLongMeasurement measurement =
+ meter
+ .gaugeBuilder("temperature")
+ .ofLongs()
+ .setDescription("The current temperature")
+ .setUnit("C")
+ .buildObserver();
+ measurement.record(1);
+ measurement.record(1, Attributes.of(stringKey("thing"), "engine"));
+ }
+
+ @Test
+ void noopObservableLongGauage_doesNotThrow() {
+ meter
+ .gaugeBuilder("temperature")
+ .ofLongs()
+ .setDescription("The current temperature")
+ .setUnit("C")
+ .buildWithCallback(
+ m -> {
+ m.record(1);
+ m.record(2, Attributes.of(stringKey("thing"), "engine"));
+ });
+ }
+
+ @Test
+ void noopDoubleGauage_doesNotThrow() {
+ DoubleGauge gauge =
+ meter
+ .gaugeBuilder("temperature")
+ .setDescription("The current temperature")
+ .setUnit("C")
+ .build();
+ gauge.set(1);
+ gauge.set(2, Attributes.of(stringKey("thing"), "engine"));
+ gauge.set(2, Attributes.of(stringKey("thing"), "engine"), Context.current());
+
+ ObservableDoubleMeasurement measurement =
+ meter
+ .gaugeBuilder("temperature")
+ .setDescription("The current temperature")
+ .setUnit("C")
+ .buildObserver();
+ measurement.record(1.0);
+ measurement.record(1.0, Attributes.of(stringKey("thing"), "engine"));
+ }
+
+ @Test
+ void noopObservableDoubleGauage_doesNotThrow() {
+ meter
+ .gaugeBuilder("temperature")
+ .setDescription("The current temperature")
+ .setUnit("C")
+ .buildWithCallback(
+ m -> {
+ m.record(1.0e1);
+ m.record(-27.4, Attributes.of(stringKey("thing"), "engine"));
+ });
+ }
+
+ @Test
+ void noopObservableLongCounter_doesNotThrow() {
+ meter
+ .counterBuilder("temperature")
+ .setDescription("The current temperature")
+ .setUnit("C")
+ .buildWithCallback(
+ m -> {
+ m.record(1);
+ m.record(2, Attributes.of(stringKey("thing"), "engine"));
+ });
+ }
+
+ @Test
+ void noopObservableDoubleCounter_doesNotThrow() {
+ meter
+ .counterBuilder("temperature")
+ .ofDoubles()
+ .setDescription("The current temperature")
+ .setUnit("C")
+ .buildWithCallback(
+ m -> {
+ m.record(1.0e1);
+ m.record(-27.4, Attributes.of(stringKey("thing"), "engine"));
+ });
+ }
+
+ @Test
+ void noopObservableLongUpDownCounter_doesNotThrow() {
+ meter
+ .upDownCounterBuilder("temperature")
+ .setDescription("The current temperature")
+ .setUnit("C")
+ .buildWithCallback(
+ m -> {
+ m.record(1);
+ m.record(2, Attributes.of(stringKey("thing"), "engine"));
+ });
+ }
+
+ @Test
+ void noopObservableDoubleUpDownCounter_doesNotThrow() {
+ meter
+ .upDownCounterBuilder("temperature")
+ .ofDoubles()
+ .setDescription("The current temperature")
+ .setUnit("C")
+ .buildWithCallback(
+ m -> {
+ m.record(1.0e1);
+ m.record(-27.4, Attributes.of(stringKey("thing"), "engine"));
+ });
+ }
+
+ @Test
+ void noopBatchCallback_doesNotThrow() {
+ meter.batchCallback(() -> {}, null);
+ }
+}
diff --git a/api/all/src/testFixtures/java/io/opentelemetry/api/trace/AbstractDefaultTracerTest.java b/api/all/src/testFixtures/java/io/opentelemetry/api/trace/AbstractDefaultTracerTest.java
new file mode 100644
index 00000000000..1933e289d5b
--- /dev/null
+++ b/api/all/src/testFixtures/java/io/opentelemetry/api/trace/AbstractDefaultTracerTest.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.trace;
+
+import static io.opentelemetry.api.common.AttributeKey.stringKey;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.context.Context;
+import java.time.Instant;
+import java.util.concurrent.TimeUnit;
+import org.junit.jupiter.api.Test;
+
+/** Unit tests for {@link DefaultTracer}. */
+// Need to suppress warnings for MustBeClosed because Android 14 does not support
+// try-with-resources.
+@SuppressWarnings("MustBeClosedChecker")
+public abstract class AbstractDefaultTracerTest {
+ private final Tracer defaultTracer = getTracer();
+ private static final String SPAN_NAME = "MySpanName";
+ private static final SpanContext spanContext =
+ SpanContext.create(
+ "00000000000000000000000000000061",
+ "0000000000000061",
+ TraceFlags.getDefault(),
+ TraceState.getDefault());
+
+ public abstract Tracer getTracer();
+
+ public abstract TracerProvider getTracerProvider();
+
+ @Test
+ void returnsDefaultTracer() {
+ TracerProvider tracerProvider = getTracerProvider();
+ Class extends Tracer> want = defaultTracer.getClass();
+ assertThat(
+ tracerProvider
+ .tracerBuilder("test")
+ .setSchemaUrl("schema")
+ .setInstrumentationVersion("1")
+ .build())
+ .isInstanceOf(want);
+ assertThat(tracerProvider.get("test")).isInstanceOf(want);
+ assertThat(tracerProvider.get("test", "1.0")).isInstanceOf(want);
+ }
+
+ @Test
+ void defaultSpanBuilderWithName() {
+ assertThat(defaultTracer.spanBuilder(SPAN_NAME).startSpan().getSpanContext().isValid())
+ .isFalse();
+ }
+
+ @Test
+ void spanContextPropagationExplicitParent() {
+ assertThat(
+ defaultTracer
+ .spanBuilder(SPAN_NAME)
+ .setParent(Context.root().with(Span.wrap(spanContext)))
+ .startSpan()
+ .getSpanContext())
+ .isSameAs(spanContext);
+
+ SpanBuilder builder = defaultTracer.spanBuilder(SPAN_NAME);
+ assertThat(builder.setParent(null)).isSameAs(builder);
+ }
+
+ @Test
+ void spanContextPropagation() {
+ Span parent = Span.wrap(spanContext);
+
+ Span span =
+ defaultTracer.spanBuilder(SPAN_NAME).setParent(Context.root().with(parent)).startSpan();
+ assertThat(span.getSpanContext()).isSameAs(spanContext);
+ }
+
+ @Test
+ void noSpanContextMakesInvalidSpans() {
+ Span span = defaultTracer.spanBuilder(SPAN_NAME).startSpan();
+ assertThat(span.getSpanContext()).isSameAs(SpanContext.getInvalid());
+ }
+
+ @Test
+ void spanContextPropagation_fromContext() {
+ Context context = Context.current().with(Span.wrap(spanContext));
+
+ Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).startSpan();
+ assertThat(span.getSpanContext()).isSameAs(spanContext);
+ }
+
+ @Test
+ void spanContextPropagation_fromContextAfterNoParent() {
+ Context context = Context.current().with(Span.wrap(spanContext));
+
+ Span span = defaultTracer.spanBuilder(SPAN_NAME).setNoParent().setParent(context).startSpan();
+ assertThat(span.getSpanContext()).isSameAs(spanContext);
+ }
+
+ @Test
+ void spanContextPropagation_fromContextThenNoParent() {
+ Context context = Context.current().with(Span.wrap(spanContext));
+
+ Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).setNoParent().startSpan();
+ assertThat(span.getSpanContext()).isEqualTo(SpanContext.getInvalid());
+ }
+
+ @Test
+ void doNotCrash_NoopImplementation() {
+ assertThatCode(
+ () -> {
+ SpanBuilder spanBuilder = defaultTracer.spanBuilder(null);
+ spanBuilder.setSpanKind(null);
+ spanBuilder.setParent(null);
+ spanBuilder.setNoParent();
+ spanBuilder.addLink(null);
+ spanBuilder.addLink(null, Attributes.empty());
+ spanBuilder.addLink(SpanContext.getInvalid(), null);
+ spanBuilder.setAttribute((String) null, "foo");
+ spanBuilder.setAttribute("foo", null);
+ spanBuilder.setAttribute(null, 0L);
+ spanBuilder.setAttribute(null, 0.0);
+ spanBuilder.setAttribute(null, false);
+ spanBuilder.setAttribute((AttributeKey) null, "foo");
+ spanBuilder.setAttribute(stringKey(null), "foo");
+ spanBuilder.setAttribute(stringKey(""), "foo");
+ spanBuilder.setAttribute(stringKey("foo"), null);
+ spanBuilder.setStartTimestamp(-1, TimeUnit.MILLISECONDS);
+ spanBuilder.setStartTimestamp(1, null);
+ spanBuilder.setParent(Context.root().with(Span.wrap(null)));
+ spanBuilder.setParent(Context.root());
+ spanBuilder.setNoParent();
+ spanBuilder.addLink(Span.getInvalid().getSpanContext());
+ spanBuilder.addLink(Span.getInvalid().getSpanContext(), Attributes.empty());
+ spanBuilder.setAttribute("key", "value");
+ spanBuilder.setAttribute("key", 12345L);
+ spanBuilder.setAttribute("key", .12345);
+ spanBuilder.setAttribute("key", true);
+ spanBuilder.setAttribute(stringKey("key"), "value");
+ spanBuilder.setAllAttributes(Attributes.of(stringKey("key"), "value"));
+ spanBuilder.setAllAttributes(Attributes.empty());
+ spanBuilder.setAllAttributes(null);
+ spanBuilder.setStartTimestamp(12345L, TimeUnit.NANOSECONDS);
+ spanBuilder.setStartTimestamp(Instant.EPOCH);
+ spanBuilder.setStartTimestamp(null);
+ assertThat(spanBuilder.startSpan().getSpanContext().isValid()).isFalse();
+ })
+ .doesNotThrowAnyException();
+ }
+}
diff --git a/api/incubator/build.gradle.kts b/api/incubator/build.gradle.kts
index 3dfa0e79a3c..b28295de6d0 100644
--- a/api/incubator/build.gradle.kts
+++ b/api/incubator/build.gradle.kts
@@ -15,6 +15,7 @@ dependencies {
annotationProcessor("com.google.auto.value:auto-value")
testImplementation(project(":sdk:testing"))
+ testImplementation(testFixtures(project(":api:all")))
testImplementation("io.opentelemetry.semconv:opentelemetry-semconv-incubating")
diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java
new file mode 100644
index 00000000000..3e8dce08e74
--- /dev/null
+++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLogger.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.incubator.logs;
+
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.Value;
+import io.opentelemetry.api.logs.LogRecordBuilder;
+import io.opentelemetry.api.logs.Logger;
+import io.opentelemetry.api.logs.Severity;
+import io.opentelemetry.context.Context;
+import java.time.Instant;
+import java.util.concurrent.TimeUnit;
+
+class ExtendedDefaultLogger implements ExtendedLogger {
+
+ private static final Logger INSTANCE = new ExtendedDefaultLogger();
+ private static final LogRecordBuilder NOOP_LOG_RECORD_BUILDER = new NoopLogRecordBuilder();
+
+ private ExtendedDefaultLogger() {}
+
+ static Logger getNoop() {
+ return INSTANCE;
+ }
+
+ @Override
+ public LogRecordBuilder logRecordBuilder() {
+ return NOOP_LOG_RECORD_BUILDER;
+ }
+
+ private static final class NoopLogRecordBuilder implements ExtendedLogRecordBuilder {
+
+ private NoopLogRecordBuilder() {}
+
+ @Override
+ public LogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) {
+ return this;
+ }
+
+ @Override
+ public LogRecordBuilder setTimestamp(Instant instant) {
+ return this;
+ }
+
+ @Override
+ public LogRecordBuilder setObservedTimestamp(long timestamp, TimeUnit unit) {
+ return this;
+ }
+
+ @Override
+ public LogRecordBuilder setObservedTimestamp(Instant instant) {
+ return this;
+ }
+
+ @Override
+ public LogRecordBuilder setContext(Context context) {
+ return this;
+ }
+
+ @Override
+ public LogRecordBuilder setSeverity(Severity severity) {
+ return this;
+ }
+
+ @Override
+ public LogRecordBuilder setSeverityText(String severityText) {
+ return this;
+ }
+
+ @Override
+ public LogRecordBuilder setBody(String body) {
+ return this;
+ }
+
+ @Override
+ public LogRecordBuilder setBody(Value> body) {
+ return this;
+ }
+
+ @Override
+ public LogRecordBuilder setAttribute(AttributeKey key, T value) {
+ return this;
+ }
+
+ @Override
+ public void emit() {}
+ }
+}
diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerProvider.java
new file mode 100644
index 00000000000..6cf93296689
--- /dev/null
+++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerProvider.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.incubator.logs;
+
+import io.opentelemetry.api.logs.Logger;
+import io.opentelemetry.api.logs.LoggerBuilder;
+import io.opentelemetry.api.logs.LoggerProvider;
+
+public class ExtendedDefaultLoggerProvider implements LoggerProvider {
+
+ private static final LoggerProvider INSTANCE = new ExtendedDefaultLoggerProvider();
+ private static final LoggerBuilder NOOP_BUILDER = new NoopLoggerBuilder();
+
+ private ExtendedDefaultLoggerProvider() {}
+
+ public static LoggerProvider getNoop() {
+ return INSTANCE;
+ }
+
+ @Override
+ public LoggerBuilder loggerBuilder(String instrumentationScopeName) {
+ return NOOP_BUILDER;
+ }
+
+ private static class NoopLoggerBuilder implements LoggerBuilder {
+
+ @Override
+ public LoggerBuilder setSchemaUrl(String schemaUrl) {
+ return this;
+ }
+
+ @Override
+ public LoggerBuilder setInstrumentationVersion(String instrumentationVersion) {
+ return this;
+ }
+
+ @Override
+ public Logger build() {
+ return ExtendedDefaultLogger.getNoop();
+ }
+ }
+}
diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeter.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeter.java
new file mode 100644
index 00000000000..de1ec1fdefc
--- /dev/null
+++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeter.java
@@ -0,0 +1,454 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.incubator.metrics;
+
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.metrics.BatchCallback;
+import io.opentelemetry.api.metrics.DoubleCounter;
+import io.opentelemetry.api.metrics.DoubleCounterBuilder;
+import io.opentelemetry.api.metrics.DoubleGauge;
+import io.opentelemetry.api.metrics.DoubleGaugeBuilder;
+import io.opentelemetry.api.metrics.DoubleHistogram;
+import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
+import io.opentelemetry.api.metrics.DoubleUpDownCounter;
+import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder;
+import io.opentelemetry.api.metrics.LongCounter;
+import io.opentelemetry.api.metrics.LongCounterBuilder;
+import io.opentelemetry.api.metrics.LongGauge;
+import io.opentelemetry.api.metrics.LongGaugeBuilder;
+import io.opentelemetry.api.metrics.LongHistogram;
+import io.opentelemetry.api.metrics.LongHistogramBuilder;
+import io.opentelemetry.api.metrics.LongUpDownCounter;
+import io.opentelemetry.api.metrics.LongUpDownCounterBuilder;
+import io.opentelemetry.api.metrics.Meter;
+import io.opentelemetry.api.metrics.ObservableDoubleCounter;
+import io.opentelemetry.api.metrics.ObservableDoubleGauge;
+import io.opentelemetry.api.metrics.ObservableDoubleMeasurement;
+import io.opentelemetry.api.metrics.ObservableDoubleUpDownCounter;
+import io.opentelemetry.api.metrics.ObservableLongCounter;
+import io.opentelemetry.api.metrics.ObservableLongGauge;
+import io.opentelemetry.api.metrics.ObservableLongMeasurement;
+import io.opentelemetry.api.metrics.ObservableLongUpDownCounter;
+import io.opentelemetry.api.metrics.ObservableMeasurement;
+import io.opentelemetry.context.Context;
+import java.util.function.Consumer;
+import javax.annotation.concurrent.ThreadSafe;
+
+/**
+ * No-op implementation of {@link Meter}.
+ *
+ * This implementation should induce as close to zero overhead as possible.
+ */
+@ThreadSafe
+class ExtendedDefaultMeter implements Meter {
+
+ private static final Meter INSTANCE = new ExtendedDefaultMeter();
+
+ private static final LongCounterBuilder NOOP_LONG_COUNTER_BUILDER = new NoopLongCounterBuilder();
+ private static final LongUpDownCounterBuilder NOOP_LONG_UP_DOWN_COUNTER_BUILDER =
+ new NoopLongUpDownCounterBuilder();
+ private static final DoubleHistogramBuilder NOOP_DOUBLE_HISTOGRAM_BUILDER =
+ new NoopDoubleHistogramBuilder();
+ private static final DoubleGaugeBuilder NOOP_DOUBLE_GAUGE_BUILDER = new NoopDoubleGaugeBuilder();
+ private static final BatchCallback NOOP_BATCH_CALLBACK = new BatchCallback() {};
+ private static final ObservableDoubleMeasurement NOOP_OBSERVABLE_DOUBLE_MEASUREMENT =
+ new NoopObservableDoubleMeasurement();
+ private static final ObservableLongMeasurement NOOP_OBSERVABLE_LONG_MEASUREMENT =
+ new NoopObservableLongMeasurement();
+
+ static Meter getNoop() {
+ return INSTANCE;
+ }
+
+ @Override
+ public LongCounterBuilder counterBuilder(String name) {
+ return NOOP_LONG_COUNTER_BUILDER;
+ }
+
+ @Override
+ public LongUpDownCounterBuilder upDownCounterBuilder(String name) {
+ return NOOP_LONG_UP_DOWN_COUNTER_BUILDER;
+ }
+
+ @Override
+ public DoubleHistogramBuilder histogramBuilder(String name) {
+ return NOOP_DOUBLE_HISTOGRAM_BUILDER;
+ }
+
+ @Override
+ public DoubleGaugeBuilder gaugeBuilder(String name) {
+ return NOOP_DOUBLE_GAUGE_BUILDER;
+ }
+
+ @Override
+ public BatchCallback batchCallback(
+ Runnable callback,
+ ObservableMeasurement observableMeasurement,
+ ObservableMeasurement... additionalMeasurements) {
+ return NOOP_BATCH_CALLBACK;
+ }
+
+ private ExtendedDefaultMeter() {}
+
+ private static class NoopLongCounter implements ExtendedLongCounter {
+ @Override
+ public void add(long value, Attributes attributes, Context context) {}
+
+ @Override
+ public void add(long value, Attributes attributes) {}
+
+ @Override
+ public void add(long value) {}
+ }
+
+ private static class NoopDoubleCounter implements ExtendedDoubleCounter {
+ @Override
+ public void add(double value, Attributes attributes, Context context) {}
+
+ @Override
+ public void add(double value, Attributes attributes) {}
+
+ @Override
+ public void add(double value) {}
+ }
+
+ private static class NoopLongCounterBuilder implements ExtendedLongCounterBuilder {
+ private static final LongCounter NOOP_COUNTER = new NoopLongCounter();
+ private static final ObservableLongCounter NOOP_OBSERVABLE_COUNTER =
+ new ObservableLongCounter() {};
+ private static final DoubleCounterBuilder NOOP_DOUBLE_COUNTER_BUILDER =
+ new NoopDoubleCounterBuilder();
+
+ @Override
+ public LongCounterBuilder setDescription(String description) {
+ return this;
+ }
+
+ @Override
+ public LongCounterBuilder setUnit(String unit) {
+ return this;
+ }
+
+ @Override
+ public DoubleCounterBuilder ofDoubles() {
+ return NOOP_DOUBLE_COUNTER_BUILDER;
+ }
+
+ @Override
+ public LongCounter build() {
+ return NOOP_COUNTER;
+ }
+
+ @Override
+ public ObservableLongCounter buildWithCallback(Consumer callback) {
+ return NOOP_OBSERVABLE_COUNTER;
+ }
+
+ @Override
+ public ObservableLongMeasurement buildObserver() {
+ return NOOP_OBSERVABLE_LONG_MEASUREMENT;
+ }
+ }
+
+ private static class NoopDoubleCounterBuilder implements ExtendedDoubleCounterBuilder {
+ private static final DoubleCounter NOOP_COUNTER = new NoopDoubleCounter();
+ private static final ObservableDoubleCounter NOOP_OBSERVABLE_COUNTER =
+ new ObservableDoubleCounter() {};
+
+ @Override
+ public DoubleCounterBuilder setDescription(String description) {
+ return this;
+ }
+
+ @Override
+ public DoubleCounterBuilder setUnit(String unit) {
+ return this;
+ }
+
+ @Override
+ public DoubleCounter build() {
+ return NOOP_COUNTER;
+ }
+
+ @Override
+ public ObservableDoubleCounter buildWithCallback(
+ Consumer callback) {
+ return NOOP_OBSERVABLE_COUNTER;
+ }
+
+ @Override
+ public ObservableDoubleMeasurement buildObserver() {
+ return NOOP_OBSERVABLE_DOUBLE_MEASUREMENT;
+ }
+ }
+
+ private static class NoopLongUpDownCounter implements ExtendedLongUpDownCounter {
+ @Override
+ public void add(long value, Attributes attributes, Context context) {}
+
+ @Override
+ public void add(long value, Attributes attributes) {}
+
+ @Override
+ public void add(long value) {}
+ }
+
+ private static class NoopDoubleUpDownCounter implements ExtendedDoubleUpDownCounter {
+ @Override
+ public void add(double value, Attributes attributes, Context context) {}
+
+ @Override
+ public void add(double value, Attributes attributes) {}
+
+ @Override
+ public void add(double value) {}
+ }
+
+ private static class NoopLongUpDownCounterBuilder implements ExtendedLongUpDownCounterBuilder {
+ private static final LongUpDownCounter NOOP_UP_DOWN_COUNTER = new NoopLongUpDownCounter() {};
+ private static final ObservableLongUpDownCounter NOOP_OBSERVABLE_UP_DOWN_COUNTER =
+ new ObservableLongUpDownCounter() {};
+ private static final DoubleUpDownCounterBuilder NOOP_DOUBLE_UP_DOWN_COUNTER_BUILDER =
+ new NoopDoubleUpDownCounterBuilder();
+
+ @Override
+ public LongUpDownCounterBuilder setDescription(String description) {
+ return this;
+ }
+
+ @Override
+ public LongUpDownCounterBuilder setUnit(String unit) {
+ return this;
+ }
+
+ @Override
+ public DoubleUpDownCounterBuilder ofDoubles() {
+ return NOOP_DOUBLE_UP_DOWN_COUNTER_BUILDER;
+ }
+
+ @Override
+ public LongUpDownCounter build() {
+ return NOOP_UP_DOWN_COUNTER;
+ }
+
+ @Override
+ public ObservableLongUpDownCounter buildWithCallback(
+ Consumer callback) {
+ return NOOP_OBSERVABLE_UP_DOWN_COUNTER;
+ }
+
+ @Override
+ public ObservableLongMeasurement buildObserver() {
+ return NOOP_OBSERVABLE_LONG_MEASUREMENT;
+ }
+ }
+
+ private static class NoopDoubleUpDownCounterBuilder
+ implements ExtendedDoubleUpDownCounterBuilder {
+ private static final DoubleUpDownCounter NOOP_UP_DOWN_COUNTER =
+ new NoopDoubleUpDownCounter() {};
+ private static final ObservableDoubleUpDownCounter NOOP_OBSERVABLE_UP_DOWN_COUNTER =
+ new ObservableDoubleUpDownCounter() {};
+
+ @Override
+ public DoubleUpDownCounterBuilder setDescription(String description) {
+ return this;
+ }
+
+ @Override
+ public DoubleUpDownCounterBuilder setUnit(String unit) {
+ return this;
+ }
+
+ @Override
+ public DoubleUpDownCounter build() {
+ return NOOP_UP_DOWN_COUNTER;
+ }
+
+ @Override
+ public ObservableDoubleUpDownCounter buildWithCallback(
+ Consumer callback) {
+ return NOOP_OBSERVABLE_UP_DOWN_COUNTER;
+ }
+
+ @Override
+ public ObservableDoubleMeasurement buildObserver() {
+ return NOOP_OBSERVABLE_DOUBLE_MEASUREMENT;
+ }
+ }
+
+ private static class NoopDoubleHistogram implements ExtendedDoubleHistogram {
+ @Override
+ public void record(double value, Attributes attributes, Context context) {}
+
+ @Override
+ public void record(double value, Attributes attributes) {}
+
+ @Override
+ public void record(double value) {}
+ }
+
+ private static class NoopLongHistogram implements ExtendedLongHistogram {
+ @Override
+ public void record(long value, Attributes attributes, Context context) {}
+
+ @Override
+ public void record(long value, Attributes attributes) {}
+
+ @Override
+ public void record(long value) {}
+ }
+
+ private static class NoopDoubleHistogramBuilder implements ExtendedDoubleHistogramBuilder {
+ private static final DoubleHistogram NOOP = new NoopDoubleHistogram();
+ private static final LongHistogramBuilder NOOP_LONG_HISTOGRAM_BUILDER =
+ new NoopLongHistogramBuilder();
+
+ @Override
+ public DoubleHistogramBuilder setDescription(String description) {
+ return this;
+ }
+
+ @Override
+ public DoubleHistogramBuilder setUnit(String unit) {
+ return this;
+ }
+
+ @Override
+ public LongHistogramBuilder ofLongs() {
+ return NOOP_LONG_HISTOGRAM_BUILDER;
+ }
+
+ @Override
+ public DoubleHistogram build() {
+ return NOOP;
+ }
+ }
+
+ private static class NoopLongHistogramBuilder implements ExtendedLongHistogramBuilder {
+ private static final LongHistogram NOOP = new NoopLongHistogram();
+
+ @Override
+ public LongHistogramBuilder setDescription(String description) {
+ return this;
+ }
+
+ @Override
+ public LongHistogramBuilder setUnit(String unit) {
+ return this;
+ }
+
+ @Override
+ public LongHistogram build() {
+ return NOOP;
+ }
+ }
+
+ private static class NoopDoubleGaugeBuilder implements ExtendedDoubleGaugeBuilder {
+ private static final ObservableDoubleGauge NOOP_OBSERVABLE_GAUGE =
+ new ObservableDoubleGauge() {};
+ private static final LongGaugeBuilder NOOP_LONG_GAUGE_BUILDER = new NoopLongGaugeBuilder();
+ private static final NoopDoubleGauge NOOP_GAUGE = new NoopDoubleGauge();
+
+ @Override
+ public DoubleGaugeBuilder setDescription(String description) {
+ return this;
+ }
+
+ @Override
+ public DoubleGaugeBuilder setUnit(String unit) {
+ return this;
+ }
+
+ @Override
+ public LongGaugeBuilder ofLongs() {
+ return NOOP_LONG_GAUGE_BUILDER;
+ }
+
+ @Override
+ public ObservableDoubleGauge buildWithCallback(Consumer callback) {
+ return NOOP_OBSERVABLE_GAUGE;
+ }
+
+ @Override
+ public ObservableDoubleMeasurement buildObserver() {
+ return NOOP_OBSERVABLE_DOUBLE_MEASUREMENT;
+ }
+
+ @Override
+ public DoubleGauge build() {
+ return NOOP_GAUGE;
+ }
+ }
+
+ private static class NoopDoubleGauge implements ExtendedDoubleGauge {
+ @Override
+ public void set(double value) {}
+
+ @Override
+ public void set(double value, Attributes attributes) {}
+
+ @Override
+ public void set(double value, Attributes attributes, Context context) {}
+ }
+
+ private static class NoopLongGaugeBuilder implements ExtendedLongGaugeBuilder {
+ private static final ObservableLongGauge NOOP_OBSERVABLE_GAUGE = new ObservableLongGauge() {};
+ private static final NoopLongGauge NOOP_GAUGE = new NoopLongGauge();
+
+ @Override
+ public LongGaugeBuilder setDescription(String description) {
+ return this;
+ }
+
+ @Override
+ public LongGaugeBuilder setUnit(String unit) {
+ return this;
+ }
+
+ @Override
+ public ObservableLongGauge buildWithCallback(Consumer callback) {
+ return NOOP_OBSERVABLE_GAUGE;
+ }
+
+ @Override
+ public ObservableLongMeasurement buildObserver() {
+ return NOOP_OBSERVABLE_LONG_MEASUREMENT;
+ }
+
+ @Override
+ public LongGauge build() {
+ return NOOP_GAUGE;
+ }
+ }
+
+ private static class NoopLongGauge implements ExtendedLongGauge {
+ @Override
+ public void set(long value) {}
+
+ @Override
+ public void set(long value, Attributes attributes) {}
+
+ @Override
+ public void set(long value, Attributes attributes, Context context) {}
+ }
+
+ private static class NoopObservableDoubleMeasurement implements ObservableDoubleMeasurement {
+ @Override
+ public void record(double value) {}
+
+ @Override
+ public void record(double value, Attributes attributes) {}
+ }
+
+ private static class NoopObservableLongMeasurement implements ObservableLongMeasurement {
+ @Override
+ public void record(long value) {}
+
+ @Override
+ public void record(long value, Attributes attributes) {}
+ }
+}
diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterProvider.java
new file mode 100644
index 00000000000..3eeca2081f8
--- /dev/null
+++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterProvider.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.incubator.metrics;
+
+import io.opentelemetry.api.metrics.Meter;
+import io.opentelemetry.api.metrics.MeterBuilder;
+import io.opentelemetry.api.metrics.MeterProvider;
+
+/** A {@link MeterProvider} that does nothing. */
+public class ExtendedDefaultMeterProvider implements MeterProvider {
+ @Override
+ public MeterBuilder meterBuilder(String instrumentationScopeName) {
+ return BUILDER_INSTANCE;
+ }
+
+ private static final ExtendedDefaultMeterProvider INSTANCE = new ExtendedDefaultMeterProvider();
+ private static final MeterBuilder BUILDER_INSTANCE = new NoopMeterBuilder();
+
+ public static MeterProvider getNoop() {
+ return INSTANCE;
+ }
+
+ private ExtendedDefaultMeterProvider() {}
+
+ private static class NoopMeterBuilder implements MeterBuilder {
+
+ @Override
+ public MeterBuilder setSchemaUrl(String schemaUrl) {
+ return this;
+ }
+
+ @Override
+ public MeterBuilder setInstrumentationVersion(String instrumentationScopeVersion) {
+ return this;
+ }
+
+ @Override
+ public Meter build() {
+ return ExtendedDefaultMeter.getNoop();
+ }
+ }
+}
diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracer.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracer.java
new file mode 100644
index 00000000000..948f17e9996
--- /dev/null
+++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracer.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.incubator.trace;
+
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.incubator.propagation.ExtendedContextPropagators;
+import io.opentelemetry.api.internal.ApiUsageLogger;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.SpanBuilder;
+import io.opentelemetry.api.trace.SpanContext;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.context.propagation.ContextPropagators;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+/** No-op implementation of {@link ExtendedTracer}. */
+@ThreadSafe
+final class ExtendedDefaultTracer implements ExtendedTracer {
+
+ private static final Tracer INSTANCE = new ExtendedDefaultTracer();
+
+ static Tracer getNoop() {
+ return INSTANCE;
+ }
+
+ @Override
+ public SpanBuilder spanBuilder(String spanName) {
+ return NoopSpanBuilder.create();
+ }
+
+ private ExtendedDefaultTracer() {}
+
+ // Noop implementation of Span.Builder.
+ private static final class NoopSpanBuilder implements ExtendedSpanBuilder {
+ static NoopSpanBuilder create() {
+ return new NoopSpanBuilder();
+ }
+
+ @Nullable private SpanContext spanContext;
+
+ @Override
+ public Span startSpan() {
+ if (spanContext == null) {
+ spanContext = Span.current().getSpanContext();
+ }
+
+ return Span.wrap(spanContext);
+ }
+
+ @Override
+ public NoopSpanBuilder setParent(Context context) {
+ if (context == null) {
+ ApiUsageLogger.log("context is null");
+ return this;
+ }
+ spanContext = Span.fromContext(context).getSpanContext();
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder setParentFrom(
+ ContextPropagators propagators, Map carrier) {
+ setParent(ExtendedContextPropagators.extractTextMapPropagationContext(carrier, propagators));
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder setNoParent() {
+ spanContext = SpanContext.getInvalid();
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder addLink(SpanContext spanContext) {
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder addLink(SpanContext spanContext, Attributes attributes) {
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder setAttribute(String key, String value) {
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder setAttribute(String key, long value) {
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder setAttribute(String key, double value) {
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder setAttribute(String key, boolean value) {
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder setAttribute(AttributeKey key, T value) {
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder setAllAttributes(Attributes attributes) {
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder setSpanKind(SpanKind spanKind) {
+ return this;
+ }
+
+ @Override
+ public NoopSpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) {
+ return this;
+ }
+
+ @Override
+ public T startAndCall(SpanCallable spanCallable) throws E {
+ return spanCallable.callInSpan();
+ }
+
+ @Override
+ public T startAndCall(
+ SpanCallable spanCallable, BiConsumer handleException) throws E {
+ return spanCallable.callInSpan();
+ }
+
+ @Override
+ public void startAndRun(SpanRunnable runnable) throws E {
+ runnable.runInSpan();
+ }
+
+ @Override
+ public void startAndRun(
+ SpanRunnable runnable, BiConsumer handleException) throws E {
+ runnable.runInSpan();
+ }
+
+ private NoopSpanBuilder() {}
+ }
+}
diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerBuilder.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerBuilder.java
new file mode 100644
index 00000000000..20469674ae5
--- /dev/null
+++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerBuilder.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.incubator.trace;
+
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.TracerBuilder;
+
+final class ExtendedDefaultTracerBuilder implements TracerBuilder {
+ private static final ExtendedDefaultTracerBuilder INSTANCE = new ExtendedDefaultTracerBuilder();
+
+ static TracerBuilder getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ public TracerBuilder setSchemaUrl(String schemaUrl) {
+ return this;
+ }
+
+ @Override
+ public TracerBuilder setInstrumentationVersion(String instrumentationScopeVersion) {
+ return this;
+ }
+
+ @Override
+ public Tracer build() {
+ return ExtendedDefaultTracer.getNoop();
+ }
+}
diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerProvider.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerProvider.java
new file mode 100644
index 00000000000..b7bd2133ad7
--- /dev/null
+++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerProvider.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.incubator.trace;
+
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.TracerBuilder;
+import io.opentelemetry.api.trace.TracerProvider;
+import javax.annotation.concurrent.ThreadSafe;
+
+@ThreadSafe
+public class ExtendedDefaultTracerProvider implements TracerProvider {
+
+ private static final TracerProvider INSTANCE = new ExtendedDefaultTracerProvider();
+
+ public static TracerProvider getNoop() {
+ return INSTANCE;
+ }
+
+ @Override
+ public Tracer get(String instrumentationScopeName) {
+ return ExtendedDefaultTracer.getNoop();
+ }
+
+ @Override
+ public Tracer get(String instrumentationScopeName, String instrumentationScopeVersion) {
+ return ExtendedDefaultTracer.getNoop();
+ }
+
+ @Override
+ public TracerBuilder tracerBuilder(String instrumentationScopeName) {
+ return ExtendedDefaultTracerBuilder.getInstance();
+ }
+
+ private ExtendedDefaultTracerProvider() {}
+}
diff --git a/api/incubator/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json b/api/incubator/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json
new file mode 100644
index 00000000000..d9abd56c422
--- /dev/null
+++ b/api/incubator/src/main/resources/META-INF/native-image/io.opentelemetry/opentelemetry-api/reflect-config.json
@@ -0,0 +1,38 @@
+[
+ {
+ "methods": [
+ {
+ "name": "getNoop",
+ "parameterTypes": []
+ }
+ ],
+ "name": "io.opentelemetry.api.incubator.logs.ExtendedDefaultLoggerProvider"
+ },
+ {
+ "methods": [
+ {
+ "name": "getNoop",
+ "parameterTypes": []
+ }
+ ],
+ "name": "io.opentelemetry.api.incubator.metrics.ExtendedDefaultMeterProvider"
+ },
+ {
+ "methods": [
+ {
+ "name": "getNoop",
+ "parameterTypes": []
+ }
+ ],
+ "name": "io.opentelemetry.api.incubator.trace.ExtendedDefaultTracerProvider"
+ },
+ {
+ "methods": [
+ {
+ "name": "getNoop",
+ "parameterTypes": []
+ }
+ ],
+ "name": "io.opentelemetry.api.incubator.ExtendedDefaultOpenTelemetry"
+ }
+]
diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java
new file mode 100644
index 00000000000..b33c29c8194
--- /dev/null
+++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.incubator;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import io.opentelemetry.api.AbstractOpenTelemetryTest;
+import io.opentelemetry.api.OpenTelemetry;
+import io.opentelemetry.api.incubator.logs.ExtendedDefaultLoggerProvider;
+import io.opentelemetry.api.incubator.logs.ExtendedLogger;
+import io.opentelemetry.api.incubator.metrics.ExtendedDefaultMeterProvider;
+import io.opentelemetry.api.incubator.metrics.ExtendedLongCounterBuilder;
+import io.opentelemetry.api.incubator.trace.ExtendedDefaultTracerProvider;
+import io.opentelemetry.api.incubator.trace.ExtendedTracer;
+import io.opentelemetry.api.logs.LoggerProvider;
+import io.opentelemetry.api.metrics.MeterProvider;
+import io.opentelemetry.api.trace.TracerProvider;
+import io.opentelemetry.context.propagation.ContextPropagators;
+import org.junit.jupiter.api.Test;
+
+class ExtendedOpenTelemetryTest extends AbstractOpenTelemetryTest {
+
+ @Override
+ protected TracerProvider getTracerProvider() {
+ return ExtendedDefaultTracerProvider.getNoop();
+ }
+
+ @Override
+ protected MeterProvider getMeterProvider() {
+ return ExtendedDefaultMeterProvider.getNoop();
+ }
+
+ @Override
+ protected LoggerProvider getLoggerProvider() {
+ return ExtendedDefaultLoggerProvider.getNoop();
+ }
+
+ @Test
+ void incubatingApiIsLoaded() {
+ assertIsExtended(OpenTelemetry.noop());
+ assertIsExtended(OpenTelemetry.propagating(ContextPropagators.noop()));
+ }
+
+ private static void assertIsExtended(OpenTelemetry openTelemetry) {
+ assertThat(openTelemetry.getMeter("test").counterBuilder("test"))
+ .isInstanceOf(ExtendedLongCounterBuilder.class);
+ assertThat(openTelemetry.getLogsBridge().get("test")).isInstanceOf(ExtendedLogger.class);
+ assertThat(openTelemetry.getTracer("test")).isInstanceOf(ExtendedTracer.class);
+ }
+}
diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerTest.java
new file mode 100644
index 00000000000..e558b53fcf1
--- /dev/null
+++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedDefaultLoggerTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.incubator.logs;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import io.opentelemetry.api.common.Value;
+import io.opentelemetry.api.logs.AbstractDefaultLoggerTest;
+import io.opentelemetry.api.logs.Logger;
+import io.opentelemetry.api.logs.LoggerProvider;
+import org.junit.jupiter.api.Test;
+
+class ExtendedDefaultLoggerTest extends AbstractDefaultLoggerTest {
+
+ @Override
+ protected LoggerProvider getLoggerProvider() {
+ return ExtendedDefaultLoggerProvider.getNoop();
+ }
+
+ @Override
+ protected Logger getLogger() {
+ return ExtendedDefaultLogger.getNoop();
+ }
+
+ @Test
+ void incubatingApiIsLoaded() {
+ Logger logger = LoggerProvider.noop().get("test");
+
+ assertThat(logger).isInstanceOf(ExtendedLogger.class);
+ ExtendedLogRecordBuilder builder = (ExtendedLogRecordBuilder) logger.logRecordBuilder();
+ assertThat(builder).isInstanceOf(ExtendedLogRecordBuilder.class);
+ assertThat(builder.setBody(Value.of(0))).isSameAs(builder);
+ }
+}
diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterTest.java
new file mode 100644
index 00000000000..3d342a33661
--- /dev/null
+++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/metrics/ExtendedDefaultMeterTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.incubator.metrics;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import io.opentelemetry.api.OpenTelemetry;
+import io.opentelemetry.api.metrics.AbstractDefaultMeterTest;
+import io.opentelemetry.api.metrics.Meter;
+import io.opentelemetry.api.metrics.MeterProvider;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class ExtendedDefaultMeterTest extends AbstractDefaultMeterTest {
+
+ @Override
+ protected Meter getMeter() {
+ return ExtendedDefaultMeter.getNoop();
+ }
+
+ @Override
+ protected MeterProvider getMeterProvider() {
+ return ExtendedDefaultMeterProvider.getNoop();
+ }
+
+ @Test
+ public void incubatingApiIsLoaded() {
+ Meter meter = MeterProvider.noop().get("test");
+ assertThat(meter).isSameAs(OpenTelemetry.noop().getMeter("test"));
+
+ Assertions.assertThat(meter.gaugeBuilder("test").ofLongs())
+ .isInstanceOf(ExtendedLongGaugeBuilder.class);
+ Assertions.assertThat(meter.gaugeBuilder("test").ofLongs().build())
+ .isInstanceOf(ExtendedLongGauge.class);
+ Assertions.assertThat(meter.gaugeBuilder("test"))
+ .isInstanceOf(ExtendedDoubleGaugeBuilder.class);
+ Assertions.assertThat(meter.gaugeBuilder("test").build())
+ .isInstanceOf(ExtendedDoubleGauge.class);
+
+ Assertions.assertThat(meter.histogramBuilder("test").ofLongs())
+ .isInstanceOf(ExtendedLongHistogramBuilder.class);
+ Assertions.assertThat(meter.histogramBuilder("test").ofLongs().build())
+ .isInstanceOf(ExtendedLongHistogram.class);
+ Assertions.assertThat(meter.histogramBuilder("test"))
+ .isInstanceOf(ExtendedDoubleHistogramBuilder.class);
+ Assertions.assertThat(meter.histogramBuilder("test").build())
+ .isInstanceOf(ExtendedDoubleHistogram.class);
+
+ Assertions.assertThat(meter.counterBuilder("test"))
+ .isInstanceOf(ExtendedLongCounterBuilder.class);
+ Assertions.assertThat(meter.counterBuilder("test").build())
+ .isInstanceOf(ExtendedLongCounter.class);
+ Assertions.assertThat(meter.counterBuilder("test").ofDoubles())
+ .isInstanceOf(ExtendedDoubleCounterBuilder.class);
+ Assertions.assertThat(meter.counterBuilder("test").ofDoubles().build())
+ .isInstanceOf(ExtendedDoubleCounter.class);
+
+ Assertions.assertThat(meter.upDownCounterBuilder("test"))
+ .isInstanceOf(ExtendedLongUpDownCounterBuilder.class);
+ Assertions.assertThat(meter.upDownCounterBuilder("test").build())
+ .isInstanceOf(ExtendedLongUpDownCounter.class);
+ Assertions.assertThat(meter.upDownCounterBuilder("test").ofDoubles())
+ .isInstanceOf(ExtendedDoubleUpDownCounterBuilder.class);
+ Assertions.assertThat(meter.upDownCounterBuilder("test").ofDoubles().build())
+ .isInstanceOf(ExtendedDoubleUpDownCounter.class);
+ }
+}
diff --git a/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerTest.java b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerTest.java
new file mode 100644
index 00000000000..1550796d42d
--- /dev/null
+++ b/api/incubator/src/test/java/io/opentelemetry/api/incubator/trace/ExtendedDefaultTracerTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.api.incubator.trace;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import io.opentelemetry.api.OpenTelemetry;
+import io.opentelemetry.api.trace.AbstractDefaultTracerTest;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.TracerProvider;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+class ExtendedDefaultTracerTest extends AbstractDefaultTracerTest {
+
+ @Override
+ public Tracer getTracer() {
+ return ExtendedDefaultTracer.getNoop();
+ }
+
+ @Override
+ public TracerProvider getTracerProvider() {
+ return ExtendedDefaultTracerProvider.getNoop();
+ }
+
+ @Test
+ public void incubatingApiIsLoaded() {
+ Tracer tracer = TracerProvider.noop().get("test");
+ assertThat(tracer).isSameAs(OpenTelemetry.noop().getTracer("test"));
+
+ assertThat(tracer).isInstanceOf(ExtendedTracer.class);
+ assertThat(tracer.spanBuilder("test")).isInstanceOf(ExtendedSpanBuilder.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void incubatingApi() {
+ ExtendedSpanBuilder spanBuilder =
+ (ExtendedSpanBuilder) ExtendedDefaultTracer.getNoop().spanBuilder("test");
+ assertThat(spanBuilder.setParentFrom(null, null)).isSameAs(spanBuilder);
+
+ SpanRunnable spanRunnable = Mockito.mock(SpanRunnable.class);
+
+ spanBuilder.startAndRun(spanRunnable);
+ Mockito.verify(spanRunnable).runInSpan();
+ Mockito.reset(spanRunnable);
+
+ spanBuilder.startAndRun(spanRunnable, null);
+ Mockito.verify(spanRunnable).runInSpan();
+ Mockito.reset(spanRunnable);
+
+ SpanCallable spanCallable = Mockito.mock(SpanCallable.class);
+
+ spanBuilder.startAndCall(spanCallable);
+ Mockito.verify(spanCallable).callInSpan();
+ Mockito.reset(spanCallable);
+
+ spanBuilder.startAndCall(spanCallable, null);
+ Mockito.verify(spanCallable).callInSpan();
+ Mockito.reset(spanCallable);
+ }
+}
diff --git a/integration-tests/graal-incubating/build.gradle.kts b/integration-tests/graal-incubating/build.gradle.kts
new file mode 100644
index 00000000000..d050e01dee8
--- /dev/null
+++ b/integration-tests/graal-incubating/build.gradle.kts
@@ -0,0 +1,48 @@
+plugins {
+ id("otel.java-conventions")
+ id("org.graalvm.buildtools.native")
+}
+
+description = "OpenTelemetry Graal Integration Tests (Incubating)"
+otelJava.moduleName.set("io.opentelemetry.graal.integration.tests.incubating")
+
+sourceSets {
+ main {
+ // We need to ensure that we have the shadowed classes on the classpath, without this
+ // we will get the <:sdk:trace-shaded-deps> classes only, without the shadowed ones
+ val traceShadedDeps = project(":sdk:trace-shaded-deps")
+ output.dir(traceShadedDeps.file("build/extracted/shadow"), "builtBy" to ":sdk:trace-shaded-deps:extractShadowJar")
+ }
+}
+
+dependencies {
+ implementation(project(":sdk:all"))
+ implementation(project(":sdk:trace-shaded-deps"))
+ implementation(project(":exporters:otlp:all"))
+ implementation(project(":api:incubator"))
+}
+
+// org.graalvm.buildtools.native pluging requires java 11+ as of version 0.9.26
+// https://github.com/graalvm/native-build-tools/blob/master/docs/src/docs/asciidoc/index.adoc
+tasks {
+ withType().configureEach {
+ sourceCompatibility = "11"
+ targetCompatibility = "11"
+ options.release.set(11)
+ }
+ withType().configureEach {
+ val testJavaVersion: String? by project
+ enabled = !testJavaVersion.equals("8")
+ }
+}
+
+graalvmNative {
+ binaries {
+ named("test") {
+ // Required as of junit 5.10.0: https://junit.org/junit5/docs/5.10.0/release-notes/#deprecations-and-breaking-changes
+ buildArgs.add("--initialize-at-build-time=org.junit.platform.launcher.core.LauncherConfig")
+ buildArgs.add("--initialize-at-build-time=org.junit.jupiter.engine.config.InstantiatingConfigurationParameterConverter")
+ }
+ }
+ toolchainDetection.set(false)
+}
diff --git a/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java b/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java
new file mode 100644
index 00000000000..8d705419452
--- /dev/null
+++ b/integration-tests/graal-incubating/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingApiTests.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.integrationtests.graal;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import io.opentelemetry.api.incubator.logs.ExtendedLogger;
+import io.opentelemetry.api.incubator.metrics.ExtendedLongCounterBuilder;
+import io.opentelemetry.api.incubator.trace.ExtendedTracer;
+import io.opentelemetry.api.logs.LoggerProvider;
+import io.opentelemetry.api.metrics.MeterProvider;
+import io.opentelemetry.api.trace.TracerProvider;
+import org.junit.jupiter.api.Test;
+
+class IncubatingApiTests {
+ @Test
+ void incubatingApiIsLoadedViaReflection() {
+ assertThat(LoggerProvider.noop().get("test")).isInstanceOf(ExtendedLogger.class);
+ assertThat(TracerProvider.noop().get("test")).isInstanceOf(ExtendedTracer.class);
+ assertThat(MeterProvider.noop().get("test").counterBuilder("test"))
+ .isInstanceOf(ExtendedLongCounterBuilder.class);
+ }
+}
diff --git a/integration-tests/graal/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingNotFoundApiTests.java b/integration-tests/graal/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingNotFoundApiTests.java
new file mode 100644
index 00000000000..ba2ba02a2c3
--- /dev/null
+++ b/integration-tests/graal/src/test/java/io/opentelemetry/integrationtests/graal/IncubatingNotFoundApiTests.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.integrationtests.graal;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import io.opentelemetry.api.logs.Logger;
+import io.opentelemetry.api.logs.LoggerProvider;
+import io.opentelemetry.api.metrics.LongCounterBuilder;
+import io.opentelemetry.api.metrics.MeterProvider;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.TracerProvider;
+import org.junit.jupiter.api.Test;
+
+class IncubatingNotFoundApiTests {
+ @Test
+ void incubatingApiIsNotFoundViaReflection() {
+ assertThat(LoggerProvider.noop().get("test")).isInstanceOf(Logger.class);
+ assertThat(TracerProvider.noop().get("test")).isInstanceOf(Tracer.class);
+ assertThat(MeterProvider.noop().get("test").counterBuilder("test"))
+ .isInstanceOf(LongCounterBuilder.class);
+ }
+}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 1ad4058a096..4bf7ca86538 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -48,6 +48,7 @@ include(":integration-tests")
include(":integration-tests:otlp")
include(":integration-tests:tracecontext")
include(":integration-tests:graal")
+include(":integration-tests:graal-incubating")
include(":opencensus-shim")
include(":opentracing-shim")
include(":perf-harness")