Allow users to access the default Clock and TestClock (#3363)

* Allow users to access the default Clock and TestClock

* Update TestClock API

* Doc

* Fix

* html

* Less newlines

* Update sdk/common/src/main/java/io/opentelemetry/sdk/common/Clock.java

Co-authored-by: John Watson <jkwatson@gmail.com>

Co-authored-by: John Watson <jkwatson@gmail.com>
This commit is contained in:
Anuraag Agrawal 2021-07-09 11:26:55 +09:00 committed by GitHub
parent 6449a84ce4
commit f90040579e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 311 additions and 265 deletions

View File

@ -1,4 +1,7 @@
Comparing source compatibility of against
***! MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.common.Clock (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++! NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.Clock getDefault()
**** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.common.InstrumentationLibraryInfo (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.InstrumentationLibraryInfo create(java.lang.String, java.lang.String, java.lang.String)

View File

@ -5,3 +5,13 @@ Comparing source compatibility of against
+++ NEW ANNOTATION: java.lang.SafeVarargs
+++ NEW METHOD: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.assertj.SpanDataAssert hasEventsSatisfyingExactly(java.util.function.Consumer[])
+++ NEW ANNOTATION: java.lang.SafeVarargs
+++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.time.TestClock (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) void advance(java.time.Duration)
+++ NEW METHOD: PUBLIC(+) void advance(long, java.util.concurrent.TimeUnit)
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.testing.time.TestClock create()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.testing.time.TestClock create(java.time.Instant)
+++ NEW METHOD: PUBLIC(+) long nanoTime()
+++ NEW METHOD: PUBLIC(+) long now()
+++ NEW METHOD: PUBLIC(+) void setTime(java.time.Instant)

View File

@ -21,6 +21,7 @@ dependencies {
implementation("com.fasterxml.jackson.core:jackson-core")
implementation("com.fasterxml.jackson.core:jackson-databind")
testImplementation(project(":sdk:testing"))
testImplementation(project(":sdk-extensions:autoconfigure"))
testImplementation("com.linecorp.armeria:armeria-junit5")

View File

@ -17,6 +17,8 @@ dependencies {
implementation("io.grpc:grpc-stub")
implementation("com.google.protobuf:protobuf-java")
testImplementation(project(":sdk:testing"))
testImplementation("io.grpc:grpc-testing")
testImplementation("org.testcontainers:junit-jupiter")

View File

@ -12,8 +12,8 @@ import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.common.Clock;
import io.opentelemetry.sdk.internal.RateLimiter;
import io.opentelemetry.sdk.internal.SystemClock;
import io.opentelemetry.sdk.trace.data.LinkData;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.opentelemetry.sdk.trace.samplers.SamplingDecision;
@ -42,7 +42,7 @@ class RateLimitingSampler implements Sampler {
RateLimitingSampler(int maxTracesPerSecond) {
this.maxTracesPerSecond = maxTracesPerSecond;
double maxBalance = maxTracesPerSecond < 1.0 ? 1.0 : maxTracesPerSecond;
this.rateLimiter = new RateLimiter(maxTracesPerSecond, maxBalance, SystemClock.getInstance());
this.rateLimiter = new RateLimiter(maxTracesPerSecond, maxBalance, Clock.getDefault());
Attributes attributes =
Attributes.of(SAMPLER_TYPE, TYPE, SAMPLER_PARAM, (double) maxTracesPerSecond);
this.onSamplingResult = SamplingResult.create(SamplingDecision.RECORD_AND_SAMPLE, attributes);

View File

@ -12,6 +12,8 @@ dependencies {
implementation(project(":api:all"))
implementation(project(":sdk:all"))
testImplementation(project(":sdk:testing"))
testImplementation("com.google.guava:guava")
compileOnly("com.sun.net.httpserver:http")

View File

@ -10,10 +10,11 @@ import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.testing.time.TestClock;
import io.opentelemetry.sdk.trace.ReadableSpan;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.data.SpanData;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -157,7 +158,7 @@ public final class TracezDataAggregatorTest {
void getSpanLatencyCounts_oneSpanPerLatencyBucket() {
for (LatencyBoundary bucket : LatencyBoundary.values()) {
Span span = tracer.spanBuilder(SPAN_NAME_ONE).startSpan();
testClock.advanceNanos(bucket.getLatencyLowerBound());
testClock.advance(Duration.ofNanos(bucket.getLatencyLowerBound()));
span.end();
}
/* getSpanLatencyCounts should return 1 span per latency bucket */
@ -181,7 +182,7 @@ public final class TracezDataAggregatorTest {
/* getOkSpans should return an empty List */
assertThat(dataAggregator.getOkSpans(SPAN_NAME_ONE, 0, Long.MAX_VALUE)).isEmpty();
span1.end();
testClock.advanceNanos(1000);
testClock.advance(Duration.ofNanos(1000));
span2.end();
/* getOkSpans should return a List with both spans */
List<SpanData> spans = dataAggregator.getOkSpans(SPAN_NAME_ONE, 0, Long.MAX_VALUE);

View File

@ -12,7 +12,7 @@ import com.google.common.collect.ImmutableMap;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.testing.time.TestClock;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.internal;
package io.opentelemetry.sdk.common;
import static org.assertj.core.api.Assertions.assertThat;

View File

@ -10,19 +10,36 @@ import javax.annotation.concurrent.ThreadSafe;
/** Interface for getting the current time. */
@ThreadSafe
public interface Clock {
/** Returns a default {@link Clock} which reads from {@linkplain System system time}. */
static Clock getDefault() {
return SystemClock.getInstance();
}
/**
* Obtains the current epoch timestamp in nanos from this clock.
* Returns the current epoch timestamp in nanos from this clock. This timestamp should only be
* used to compute a current time. To compute a duration, timestamps should always be obtained
* using {@link #nanoTime()}. For example, this usage is correct.
*
* @return the current epoch timestamp in nanos.
* <pre>{@code
* long startNanos = clock.nanoTime();
* // Spend time...
* long durationNanos = clock.nanoTime() - startNanos;
* }</pre>
*
* <p>This usage is NOT correct.
*
* <pre>{@code
* long startNanos = clock.now();
* // Spend time...
* long durationNanos = clock.now() - startNanos;
* }</pre>
*/
long now();
/**
* Returns a time measurement with nanosecond precision that can only be used to calculate elapsed
* time.
*
* @return a time measurement with nanosecond precision that can only be used to calculate elapsed
* time.
*/
long nanoTime();
}

View File

@ -3,14 +3,14 @@
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.internal;
package io.opentelemetry.sdk.common;
import io.opentelemetry.sdk.common.Clock;
import io.opentelemetry.sdk.internal.JavaVersionSpecific;
import javax.annotation.concurrent.ThreadSafe;
/** A {@link Clock} that uses {@link System#currentTimeMillis()} and {@link System#nanoTime()}. */
@ThreadSafe
public final class SystemClock implements Clock {
final class SystemClock implements Clock {
private static final SystemClock INSTANCE = new SystemClock();
@ -21,7 +21,7 @@ public final class SystemClock implements Clock {
*
* @return a {@code MillisClock}.
*/
public static SystemClock getInstance() {
static Clock getInstance() {
return INSTANCE;
}

View File

@ -33,7 +33,7 @@ import java.util.logging.Logger;
* may be used outside the multi-release JAR, e.g., in testing or when a user shades without
* creating their own multi-release JAR.
*/
class JavaVersionSpecific {
public class JavaVersionSpecific {
private static final Logger logger = Logger.getLogger(JavaVersionSpecific.class.getName());
@ -46,7 +46,7 @@ class JavaVersionSpecific {
}
/** Returns the {@link JavaVersionSpecific} for the current version of Java. */
static JavaVersionSpecific get() {
public static JavaVersionSpecific get() {
return CURRENT;
}
@ -55,7 +55,7 @@ class JavaVersionSpecific {
}
/** Returns the number of nanoseconds since the epoch (00:00:00, 01-Jan-1970, GMT). */
long currentTimeNanos() {
public long currentTimeNanos() {
return TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis());
}
}

View File

@ -1,81 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.internal;
import io.opentelemetry.api.internal.GuardedBy;
import io.opentelemetry.sdk.common.Clock;
import java.util.concurrent.TimeUnit;
import javax.annotation.concurrent.ThreadSafe;
/** A mutable {@link Clock} that allows the time to be set for testing. */
@ThreadSafe
public final class TestClock implements Clock {
@GuardedBy("this")
private long currentEpochNanos;
private TestClock(long epochNanos) {
currentEpochNanos = epochNanos;
}
/**
* Creates a clock initialized to a constant non-zero time.
*
* @return a clock initialized to a constant non-zero time.
*/
public static TestClock create() {
// Set Time to Tuesday, May 7, 2019 12:00:00 AM GMT-07:00 DST
return create(TimeUnit.MILLISECONDS.toNanos(1_557_212_400_000L));
}
/**
* Creates a clock with the given time.
*
* @param epochNanos the initial time in nanos since epoch.
* @return a new {@code TestClock} with the given time.
*/
public static TestClock create(long epochNanos) {
return new TestClock(epochNanos);
}
/**
* Sets the time.
*
* @param epochNanos the new time.
*/
public synchronized void setTime(long epochNanos) {
currentEpochNanos = epochNanos;
}
/**
* Advances the time by millis and mutates this instance.
*
* @param millis the increase in time.
*/
public synchronized void advanceMillis(long millis) {
long nanos = TimeUnit.MILLISECONDS.toNanos(millis);
currentEpochNanos += nanos;
}
/**
* Advances the time by nanos and mutates this instance.
*
* @param nanos the increase in time.
*/
public synchronized void advanceNanos(long nanos) {
currentEpochNanos += nanos;
}
@Override
public synchronized long now() {
return currentEpochNanos;
}
@Override
public synchronized long nanoTime() {
return currentEpochNanos;
}
}

View File

@ -27,7 +27,7 @@ public class ThrottlingLogger {
/** Create a new logger which will enforce a max number of messages per minute. */
public ThrottlingLogger(Logger delegate) {
this(delegate, SystemClock.getInstance());
this(delegate, Clock.getDefault());
}
// visible for testing

View File

@ -7,19 +7,22 @@ package io.opentelemetry.sdk.internal;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import java.time.Instant;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link MonotonicClock}. */
class MonotonicClockTest {
private static final long EPOCH_NANOS = 1234_000_005_678L;
private final TestClock testClock = TestClock.create(EPOCH_NANOS);
private final TestClock testClock = TestClock.create(Instant.ofEpochSecond(0, EPOCH_NANOS));
@Test
void nanoTime() {
assertThat(testClock.now()).isEqualTo(EPOCH_NANOS);
MonotonicClock monotonicClock = MonotonicClock.create(testClock);
assertThat(monotonicClock.nanoTime()).isEqualTo(testClock.nanoTime());
testClock.advanceNanos(12345);
testClock.advance(Duration.ofNanos(12345));
assertThat(monotonicClock.nanoTime()).isEqualTo(testClock.nanoTime());
}
@ -27,12 +30,12 @@ class MonotonicClockTest {
void now_PositiveIncrease() {
MonotonicClock monotonicClock = MonotonicClock.create(testClock);
assertThat(monotonicClock.now()).isEqualTo(testClock.now());
testClock.advanceNanos(3210);
testClock.advance(Duration.ofNanos(3210));
assertThat(monotonicClock.now()).isEqualTo(1234_000_008_888L);
// Initial + 1000
testClock.advanceNanos(-2210);
testClock.advance(Duration.ofNanos(-2210));
assertThat(monotonicClock.now()).isEqualTo(1234_000_006_678L);
testClock.advanceNanos(15_999_993_322L);
testClock.advance(Duration.ofNanos(15_999_993_322L));
assertThat(monotonicClock.now()).isEqualTo(1250_000_000_000L);
}
@ -40,12 +43,12 @@ class MonotonicClockTest {
void now_NegativeIncrease() {
MonotonicClock monotonicClock = MonotonicClock.create(testClock);
assertThat(monotonicClock.now()).isEqualTo(testClock.now());
testClock.advanceNanos(-3456);
testClock.advance(Duration.ofNanos(-3456));
assertThat(monotonicClock.now()).isEqualTo(1234_000_002_222L);
// Initial - 1000
testClock.advanceNanos(2456);
testClock.advance(Duration.ofNanos(2456));
assertThat(monotonicClock.now()).isEqualTo(1234_000_004_678L);
testClock.advanceNanos(-14_000_004_678L);
testClock.advance(Duration.ofNanos(-14_000_004_678L));
assertThat(monotonicClock.now()).isEqualTo(1220_000_000_000L);
}
}

View File

@ -7,6 +7,8 @@ package io.opentelemetry.sdk.internal;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
@ -32,18 +34,18 @@ class RateLimiterTest {
assertThat(limiter.trySpend(1.0)).isTrue();
assertThat(limiter.trySpend(1.0)).isFalse();
// move time 250ms forward, not enough credits to pay for 1.0 item
clock.advanceNanos(TimeUnit.MILLISECONDS.toNanos(250));
clock.advance(Duration.ofNanos(TimeUnit.MILLISECONDS.toNanos(250)));
assertThat(limiter.trySpend(1.0)).isFalse();
// move time 500ms forward, now enough credits to pay for 1.0 item
clock.advanceNanos(TimeUnit.MILLISECONDS.toNanos(500));
clock.advance(Duration.ofNanos(TimeUnit.MILLISECONDS.toNanos(500)));
assertThat(limiter.trySpend(1.0)).isTrue();
assertThat(limiter.trySpend(1.0)).isFalse();
// move time 5s forward, enough to accumulate credits for 10 messages, but it should still be
// capped at 2
clock.advanceNanos(TimeUnit.MILLISECONDS.toNanos(5000));
clock.advance(Duration.ofNanos(TimeUnit.MILLISECONDS.toNanos(5000)));
assertThat(limiter.trySpend(1.0)).isTrue();
assertThat(limiter.trySpend(1.0)).isTrue();
@ -58,7 +60,7 @@ class RateLimiterTest {
RateLimiter limiter = new RateLimiter(5.0 / 60.0, 5.0, clock);
for (int i = 0; i < 100; i++) {
assertThat(limiter.trySpend(1.0)).isTrue();
clock.advanceNanos(TimeUnit.SECONDS.toNanos(20));
clock.advance(Duration.ofNanos(TimeUnit.SECONDS.toNanos(20)));
}
}
@ -78,18 +80,18 @@ class RateLimiterTest {
assertThat(limiter.trySpend(0.25)).isTrue();
assertThat(limiter.trySpend(0.25)).isFalse();
// move time 250ms forward, not enough credits to pay for 1.0 item
clock.advanceNanos(TimeUnit.MILLISECONDS.toNanos(250));
clock.advance(Duration.ofNanos(TimeUnit.MILLISECONDS.toNanos(250)));
assertThat(limiter.trySpend(0.25)).isFalse();
// move time 500ms forward, now enough credits to pay for 1.0 item
clock.advanceNanos(TimeUnit.MILLISECONDS.toNanos(500));
clock.advance(Duration.ofNanos(TimeUnit.MILLISECONDS.toNanos(500)));
assertThat(limiter.trySpend(0.25)).isTrue();
assertThat(limiter.trySpend(0.25)).isFalse();
// move time 5s forward, enough to accumulate credits for 10 messages, but it should still be
// capped at 2
clock.advanceNanos(TimeUnit.MILLISECONDS.toNanos(5000));
clock.advance(Duration.ofNanos(TimeUnit.MILLISECONDS.toNanos(5000)));
assertThat(limiter.trySpend(0.25)).isTrue();
assertThat(limiter.trySpend(0.25)).isTrue();
@ -103,13 +105,13 @@ class RateLimiterTest {
TestClock clock = TestClock.create();
RateLimiter limiter = new RateLimiter(0.1, 1.0, clock);
clock.advanceNanos(TimeUnit.MICROSECONDS.toNanos(100));
clock.advance(Duration.ofNanos(TimeUnit.MICROSECONDS.toNanos(100)));
assertThat(limiter.trySpend(1.0)).isTrue();
assertThat(limiter.trySpend(1.0)).isFalse();
// move time 20s forward, enough to accumulate credits for 2 messages, but it should still be
// capped at 1
clock.advanceNanos(TimeUnit.MILLISECONDS.toNanos(20000));
clock.advance(Duration.ofNanos(TimeUnit.MILLISECONDS.toNanos(20000)));
assertThat(limiter.trySpend(1.0)).isTrue();
assertThat(limiter.trySpend(1.0)).isFalse();
@ -127,19 +129,21 @@ class RateLimiterTest {
assertThat(limiter.trySpend(100)).isTrue(); // consume initial (max) balance
assertThat(limiter.trySpend(1)).isFalse();
clock.advanceNanos(TimeUnit.MILLISECONDS.toNanos(49)); // add 49 credits
// add 49 credits
clock.advance(Duration.ofNanos(TimeUnit.MILLISECONDS.toNanos(49)));
assertThat(limiter.trySpend(50)).isFalse();
clock.advanceNanos(TimeUnit.MILLISECONDS.toNanos(1)); // add one credit
// add one credit
clock.advance(Duration.ofNanos(TimeUnit.MILLISECONDS.toNanos(1)));
assertThat(limiter.trySpend(50)).isTrue(); // consume accrued balance
assertThat(limiter.trySpend(1)).isFalse();
clock.advanceNanos(
TimeUnit.MILLISECONDS.toNanos(1_000_000)); // add a lot of credits (max out balance)
// add a lot of credits (max out balance)
clock.advance(Duration.ofNanos(TimeUnit.MILLISECONDS.toNanos(1_000_000)));
assertThat(limiter.trySpend(1)).isTrue(); // take one credit
clock.advanceNanos(
TimeUnit.MILLISECONDS.toNanos(1_000_000)); // add a lot of credits (max out balance)
// add a lot of credits (max out balance)
clock.advance(Duration.ofNanos(TimeUnit.MILLISECONDS.toNanos(1_000_000)));
assertThat(limiter.trySpend(101)).isFalse(); // can't consume more than max balance
assertThat(limiter.trySpend(100)).isTrue(); // consume max balance
assertThat(limiter.trySpend(1)).isFalse();

View File

@ -1,38 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.internal;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
/** Tests for {@link TestClock}. */
public final class TestClockTest {
@Test
void setAndGetTime() {
TestClock clock = TestClock.create(1234);
assertThat(clock.now()).isEqualTo(1234);
clock.setTime(9876543210L);
assertThat(clock.now()).isEqualTo(9876543210L);
}
@Test
void advanceMillis() {
TestClock clock = TestClock.create(1_500_000_000L);
clock.advanceMillis(2600);
assertThat(clock.now()).isEqualTo(4_100_000_000L);
}
@Test
void measureElapsedTime() {
TestClock clock = TestClock.create(10_000_000_001L);
long nanos1 = clock.nanoTime();
clock.setTime(11_000_000_005L);
long nanos2 = clock.nanoTime();
assertThat(nanos2 - nanos1).isEqualTo(1_000_000_004L);
}
}

View File

@ -12,6 +12,8 @@ import static org.slf4j.event.Level.WARN;
import io.github.netmikey.logunit.api.LogCapturer;
import io.opentelemetry.sdk.common.Clock;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.jupiter.api.Test;
@ -84,25 +86,25 @@ class ThrottlingLoggerTest {
assertThat(logs.size()).isEqualTo(1);
logger.log(Level.WARNING, "oh no!");
assertThat(logs.size()).isEqualTo(2);
clock.advanceMillis(30_001);
clock.advance(Duration.ofMillis(30_001));
logger.log(Level.WARNING, "oh no!");
logger.log(Level.WARNING, "oh no!");
assertThat(logs.size()).isEqualTo(4);
clock.advanceMillis(30_001);
clock.advance(Duration.ofMillis(30_001));
logger.log(Level.WARNING, "oh no 2nd minute!");
logger.log(Level.WARNING, "oh no 2nd minute!");
assertThat(logs.size()).isEqualTo(6);
clock.advanceMillis(30_001);
clock.advance(Duration.ofMillis(30_001));
logger.log(Level.WARNING, "oh no 2nd minute!");
logger.log(Level.WARNING, "oh no 2nd minute!");
assertThat(logs.size()).isEqualTo(8);
clock.advanceMillis(30_001);
clock.advance(Duration.ofMillis(30_001));
logger.log(Level.WARNING, "oh no 3rd minute!");
logger.log(Level.WARNING, "oh no 3rd minute!");
assertThat(logs.size()).isEqualTo(10);
clock.advanceMillis(30_001);
clock.advance(Duration.ofMillis(30_001));
logger.log(Level.WARNING, "oh no 3rd minute!");
logger.log(Level.WARNING, "oh no 3rd minute!");
assertThat(logs.size()).isEqualTo(12);
@ -129,13 +131,13 @@ class ThrottlingLoggerTest {
logs.assertContains(
"Too many log messages detected. Will only log once per minute from now on.");
clock.advanceMillis(60_001);
clock.advance(Duration.ofMillis(60_001));
logger.log(Level.WARNING, "oh no!");
logger.log(Level.WARNING, "oh no I should be suppressed!");
assertThat(logs.getEvents()).hasSize(8);
assertThat(logs.getEvents().get(7).getMessage()).isEqualTo("oh no!");
clock.advanceMillis(60_001);
clock.advance(Duration.ofMillis(60_001));
logger.log(Level.WARNING, "oh no!");
logger.log(Level.WARNING, "oh no I should be suppressed!");
assertThat(logs.getEvents()).hasSize(9);

View File

@ -7,8 +7,8 @@ package io.opentelemetry.sdk.metrics;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.sdk.common.Clock;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.SystemClock;
import io.opentelemetry.sdk.metrics.common.InstrumentType;
import io.opentelemetry.sdk.metrics.view.View;
import io.opentelemetry.sdk.resources.Resource;
@ -31,7 +31,7 @@ public enum TestSdk {
Meter build() {
MeterProviderSharedState meterProviderSharedState =
MeterProviderSharedState.create(
SystemClock.getInstance(),
Clock.getDefault(),
Resource.empty(),
new ViewRegistry(
new EnumMap<InstrumentType, LinkedHashMap<Pattern, View>>(

View File

@ -7,7 +7,6 @@ package io.opentelemetry.sdk.metrics;
import io.opentelemetry.api.metrics.GlobalMeterProvider;
import io.opentelemetry.sdk.common.Clock;
import io.opentelemetry.sdk.internal.SystemClock;
import io.opentelemetry.sdk.metrics.view.InstrumentSelector;
import io.opentelemetry.sdk.metrics.view.View;
import io.opentelemetry.sdk.resources.Resource;
@ -21,7 +20,7 @@ import java.util.Objects;
*/
public final class SdkMeterProviderBuilder {
private Clock clock = SystemClock.getInstance();
private Clock clock = Clock.getDefault();
private Resource resource = Resource.getDefault();
private final Map<InstrumentSelector, View> instrumentSelectorViews = new HashMap<>();

View File

@ -8,7 +8,6 @@ package io.opentelemetry.sdk.metrics;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory;
import io.opentelemetry.sdk.metrics.common.InstrumentDescriptor;
import io.opentelemetry.sdk.metrics.common.InstrumentType;
@ -17,6 +16,7 @@ import io.opentelemetry.sdk.metrics.processor.LabelsProcessor;
import io.opentelemetry.sdk.metrics.view.InstrumentSelector;
import io.opentelemetry.sdk.metrics.view.View;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

View File

@ -20,12 +20,12 @@ import io.opentelemetry.api.metrics.LongUpDownCounter;
import io.opentelemetry.api.metrics.LongValueRecorder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.data.DoubleSummaryData;
import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.data.ValueAtPercentile;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

View File

@ -7,7 +7,6 @@ package io.opentelemetry.sdk.metrics;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import io.opentelemetry.api.common.Attributes;
@ -16,9 +15,10 @@ import io.opentelemetry.api.metrics.DoubleCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link DoubleCounterSdk}. */
@ -67,7 +67,7 @@ class DoubleCounterSdkTest {
.setDescription("description")
.setUnit("ms")
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
doubleCounter.add(12d, Labels.empty());
doubleCounter.add(12d);
assertThat(sdkMeterProvider.collectAllMetrics())
@ -104,7 +104,7 @@ class DoubleCounterSdkTest {
bound.add(123.3d);
doubleCounter.add(21.4d, Labels.empty());
// Advancing time here should not matter.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.add(321.5d);
doubleCounter.add(111.1d, Labels.of("K", "V"));
assertThat(sdkMeterProvider.collectAllMetrics())
@ -136,7 +136,7 @@ class DoubleCounterSdkTest {
.containsEntry("K", "V")));
// Repeat to prove we keep previous values.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.add(222d);
doubleCounter.add(11d, Labels.empty());
assertThat(sdkMeterProvider.collectAllMetrics())

View File

@ -7,12 +7,10 @@ package io.opentelemetry.sdk.metrics;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory;
import io.opentelemetry.sdk.metrics.common.InstrumentType;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
@ -20,6 +18,8 @@ import io.opentelemetry.sdk.metrics.processor.LabelsProcessorFactory;
import io.opentelemetry.sdk.metrics.view.InstrumentSelector;
import io.opentelemetry.sdk.metrics.view.View;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link DoubleSumObserverSdk}. */
@ -69,7 +69,7 @@ class DoubleSumObserverSdkTest {
.setUnit("ms")
.setUpdater(result -> result.observe(12.1d, Labels.of("k", "v")))
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -92,7 +92,7 @@ class DoubleSumObserverSdkTest {
.attributes()
.hasSize(1)
.containsEntry("k", "v")));
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -134,7 +134,7 @@ class DoubleSumObserverSdkTest {
.setUnit("ms")
.setUpdater(result -> result.observe(12.1d, Labels.of("k", "v")))
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -157,7 +157,7 @@ class DoubleSumObserverSdkTest {
.attributes()
.hasSize(1)
.containsEntry("k", "v")));
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->

View File

@ -7,7 +7,6 @@ package io.opentelemetry.sdk.metrics;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import io.opentelemetry.api.common.Attributes;
@ -16,9 +15,10 @@ import io.opentelemetry.api.metrics.DoubleUpDownCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link DoubleUpDownCounterSdk}. */
@ -70,7 +70,7 @@ class DoubleUpDownCounterSdkTest {
.setDescription("description")
.setUnit("ms")
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
doubleUpDownCounter.add(12d, Labels.empty());
doubleUpDownCounter.add(12d);
assertThat(sdkMeterProvider.collectAllMetrics())
@ -108,7 +108,7 @@ class DoubleUpDownCounterSdkTest {
bound.add(123.3d);
doubleUpDownCounter.add(21.4d, Labels.empty());
// Advancing time here should not matter.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.add(321.5d);
doubleUpDownCounter.add(111.1d, Labels.of("K", "V"));
assertThat(sdkMeterProvider.collectAllMetrics())
@ -136,7 +136,7 @@ class DoubleUpDownCounterSdkTest {
.hasAttributes(Attributes.of(stringKey("K"), "V"))));
// Repeat to prove we keep previous values.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.add(222d);
doubleUpDownCounter.add(11d, Labels.empty());
assertThat(sdkMeterProvider.collectAllMetrics())

View File

@ -7,12 +7,10 @@ package io.opentelemetry.sdk.metrics;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory;
import io.opentelemetry.sdk.metrics.common.InstrumentType;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
@ -20,6 +18,8 @@ import io.opentelemetry.sdk.metrics.processor.LabelsProcessorFactory;
import io.opentelemetry.sdk.metrics.view.InstrumentSelector;
import io.opentelemetry.sdk.metrics.view.View;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link DoubleUpDownSumObserverSdk}. */
@ -67,7 +67,7 @@ class DoubleUpDownSumObserverSdkTest {
.doubleUpDownSumObserverBuilder("testObserver")
.setUpdater(result -> result.observe(12.1d, Labels.of("k", "v")))
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -88,7 +88,7 @@ class DoubleUpDownSumObserverSdkTest {
.attributes()
.hasSize(1)
.containsEntry("k", "v")));
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -130,7 +130,7 @@ class DoubleUpDownSumObserverSdkTest {
.doubleUpDownSumObserverBuilder("testObserver")
.setUpdater(result -> result.observe(12.1d, Labels.of("k", "v")))
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -151,7 +151,7 @@ class DoubleUpDownSumObserverSdkTest {
.attributes()
.hasSize(1)
.containsEntry("k", "v")));
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->

View File

@ -7,19 +7,18 @@ package io.opentelemetry.sdk.metrics;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link DoubleValueObserverSdk}. */
class DoubleValueObserverSdkTest {
private static final long SECOND_NANOS = 1_000_000_000;
private static final Resource RESOURCE =
Resource.create(Attributes.of(stringKey("resource_key"), "resource_value"));
private static final InstrumentationLibraryInfo INSTRUMENTATION_LIBRARY_INFO =
@ -59,7 +58,7 @@ class DoubleValueObserverSdkTest {
.setUnit("ms")
.setUpdater(result -> result.observe(12.1d, Labels.of("k", "v")))
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofSeconds(1));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -78,7 +77,7 @@ class DoubleValueObserverSdkTest {
.hasEpochNanos(testClock.now())
.hasAttributes(Attributes.builder().put("k", "v").build())
.hasValue(12.1d)));
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofSeconds(1));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->

View File

@ -15,13 +15,14 @@ import io.opentelemetry.api.metrics.DoubleValueRecorder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater;
import io.opentelemetry.sdk.metrics.data.DoubleSummaryData;
import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.data.ValueAtPercentile;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -74,7 +75,7 @@ class DoubleValueRecorderSdkTest {
.setDescription("description")
.setUnit("ms")
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
doubleRecorder.record(12d, Labels.empty());
doubleRecorder.record(12d);
assertThat(sdkMeterProvider.collectAllMetrics())
@ -108,7 +109,7 @@ class DoubleValueRecorderSdkTest {
bound.record(123.3d);
doubleRecorder.record(-13.1d, Labels.empty());
// Advancing time here should not matter.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.record(321.5d);
doubleRecorder.record(-121.5d, Labels.of("K", "V"));
assertThat(sdkMeterProvider.collectAllMetrics())
@ -137,7 +138,7 @@ class DoubleValueRecorderSdkTest {
valueAtPercentiles(-13.1d, 12.1d))))));
// Repeat to prove we don't keep previous values.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.record(222d);
doubleRecorder.record(17d, Labels.empty());
assertThat(sdkMeterProvider.collectAllMetrics())

View File

@ -7,7 +7,6 @@ package io.opentelemetry.sdk.metrics;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import io.opentelemetry.api.common.Attributes;
@ -16,9 +15,10 @@ import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link LongCounterSdk}. */
@ -67,7 +67,7 @@ class LongCounterSdkTest {
.setDescription("description")
.setUnit("By")
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
longCounter.add(12, Labels.empty());
longCounter.add(12);
assertThat(sdkMeterProvider.collectAllMetrics())
@ -104,7 +104,7 @@ class LongCounterSdkTest {
bound.add(123);
longCounter.add(21, Labels.empty());
// Advancing time here should not matter.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.add(321);
longCounter.add(111, Labels.of("K", "V"));
assertThat(sdkMeterProvider.collectAllMetrics())
@ -131,7 +131,7 @@ class LongCounterSdkTest {
.hasValue(555)));
// Repeat to prove we keep previous values.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.add(222);
longCounter.add(11, Labels.empty());
assertThat(sdkMeterProvider.collectAllMetrics())

View File

@ -7,12 +7,10 @@ package io.opentelemetry.sdk.metrics;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory;
import io.opentelemetry.sdk.metrics.common.InstrumentType;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
@ -20,6 +18,8 @@ import io.opentelemetry.sdk.metrics.processor.LabelsProcessorFactory;
import io.opentelemetry.sdk.metrics.view.InstrumentSelector;
import io.opentelemetry.sdk.metrics.view.View;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link LongSumObserverSdk}. */
@ -67,7 +67,7 @@ class LongSumObserverSdkTest {
.longSumObserverBuilder("testObserver")
.setUpdater(result -> result.observe(12, Labels.of("k", "v")))
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -88,7 +88,7 @@ class LongSumObserverSdkTest {
.attributes()
.hasSize(1)
.containsEntry("k", "v")));
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -128,7 +128,7 @@ class LongSumObserverSdkTest {
.longSumObserverBuilder("testObserver")
.setUpdater(result -> result.observe(12, Labels.of("k", "v")))
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -149,7 +149,7 @@ class LongSumObserverSdkTest {
.attributes()
.hasSize(1)
.containsEntry("k", "v")));
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->

View File

@ -7,7 +7,6 @@ package io.opentelemetry.sdk.metrics;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import io.opentelemetry.api.common.Attributes;
@ -16,9 +15,10 @@ import io.opentelemetry.api.metrics.LongUpDownCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link LongUpDownCounterSdk}. */
@ -69,7 +69,7 @@ class LongUpDownCounterSdkTest {
.setDescription("description")
.setUnit("By")
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
longUpDownCounter.add(12, Labels.empty());
longUpDownCounter.add(12);
assertThat(sdkMeterProvider.collectAllMetrics())
@ -107,7 +107,7 @@ class LongUpDownCounterSdkTest {
bound.add(123);
longUpDownCounter.add(21, Labels.empty());
// Advancing time here should not matter.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.add(321);
longUpDownCounter.add(111, Labels.of("K", "V"));
assertThat(sdkMeterProvider.collectAllMetrics())
@ -134,7 +134,7 @@ class LongUpDownCounterSdkTest {
.hasValue(555)));
// Repeat to prove we keep previous values.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.add(222);
longUpDownCounter.add(11, Labels.empty());
assertThat(sdkMeterProvider.collectAllMetrics())

View File

@ -7,12 +7,10 @@ package io.opentelemetry.sdk.metrics;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory;
import io.opentelemetry.sdk.metrics.common.InstrumentType;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
@ -20,6 +18,8 @@ import io.opentelemetry.sdk.metrics.processor.LabelsProcessorFactory;
import io.opentelemetry.sdk.metrics.view.InstrumentSelector;
import io.opentelemetry.sdk.metrics.view.View;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link LongUpDownSumObserverSdk}. */
@ -67,7 +67,7 @@ class LongUpDownSumObserverSdkTest {
.longUpDownSumObserverBuilder("testObserver")
.setUpdater(result -> result.observe(12, Labels.of("k", "v")))
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -88,7 +88,7 @@ class LongUpDownSumObserverSdkTest {
.attributes()
.hasSize(1)
.containsEntry("k", "v")));
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -130,7 +130,7 @@ class LongUpDownSumObserverSdkTest {
.longUpDownSumObserverBuilder("testObserver")
.setUpdater(result -> result.observe(12, Labels.of("k", "v")))
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -151,7 +151,7 @@ class LongUpDownSumObserverSdkTest {
.attributes()
.hasSize(1)
.containsEntry("k", "v")));
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->

View File

@ -7,19 +7,18 @@ package io.opentelemetry.sdk.metrics;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link LongValueObserverSdk}. */
class LongValueObserverSdkTest {
private static final long SECOND_NANOS = 1_000_000_000;
private static final Resource RESOURCE =
Resource.create(Attributes.of(stringKey("resource_key"), "resource_value"));
private static final InstrumentationLibraryInfo INSTRUMENTATION_LIBRARY_INFO =
@ -57,7 +56,7 @@ class LongValueObserverSdkTest {
.longValueObserverBuilder("testObserver")
.setUpdater(result -> result.observe(12, Labels.of("k", "v")))
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofSeconds(1));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->
@ -74,7 +73,7 @@ class LongValueObserverSdkTest {
.hasEpochNanos(testClock.now())
.hasAttributes(Attributes.builder().put("k", "v").build())
.hasValue(12)));
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofSeconds(1));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
metric ->

View File

@ -15,13 +15,14 @@ import io.opentelemetry.api.metrics.LongValueRecorder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.StressTestRunner.OperationUpdater;
import io.opentelemetry.sdk.metrics.data.DoubleSummaryData;
import io.opentelemetry.sdk.metrics.data.DoubleSummaryPointData;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.data.ValueAtPercentile;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -73,7 +74,7 @@ class LongValueRecorderSdkTest {
.setDescription("description")
.setUnit("By")
.build();
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
longRecorder.record(12, Labels.empty());
longRecorder.record(12);
assertThat(sdkMeterProvider.collectAllMetrics())
@ -106,7 +107,7 @@ class LongValueRecorderSdkTest {
bound.record(123);
longRecorder.record(-14, Labels.empty());
// Advancing time here should not matter.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.record(321);
longRecorder.record(-121, Labels.of("K", "V"));
assertThat(sdkMeterProvider.collectAllMetrics())
@ -135,7 +136,7 @@ class LongValueRecorderSdkTest {
valueAtPercentiles(-14, 12))))));
// Repeat to prove we don't keep previous values.
testClock.advanceNanos(SECOND_NANOS);
testClock.advance(Duration.ofNanos(SECOND_NANOS));
bound.record(222);
longRecorder.record(17, Labels.empty());
assertThat(sdkMeterProvider.collectAllMetrics())

View File

@ -6,7 +6,6 @@
package io.opentelemetry.sdk.metrics;
import static io.opentelemetry.sdk.testing.assertj.metrics.MetricAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
@ -19,7 +18,6 @@ import io.opentelemetry.api.metrics.LongValueRecorder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory;
import io.opentelemetry.sdk.metrics.common.InstrumentType;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
@ -30,6 +28,8 @@ import io.opentelemetry.sdk.metrics.data.ValueAtPercentile;
import io.opentelemetry.sdk.metrics.view.InstrumentSelector;
import io.opentelemetry.sdk.metrics.view.View;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import org.junit.jupiter.api.Test;
@ -194,7 +194,7 @@ public class SdkMeterProviderTest {
LongCounter longCounter = sdkMeter.longCounterBuilder("testLongCounter").build();
longCounter.add(10, Labels.empty());
testClock.advanceNanos(50);
testClock.advance(Duration.ofNanos(50));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
@ -216,7 +216,7 @@ public class SdkMeterProviderTest {
.hasValue(10)));
longCounter.add(10, Labels.empty());
testClock.advanceNanos(50);
testClock.advance(Duration.ofNanos(50));
assertThat(sdkMeterProvider.collectAllMetrics())
.satisfiesExactly(
@ -261,7 +261,7 @@ public class SdkMeterProviderTest {
sdkMeter.doubleValueRecorderBuilder("testDoubleValueRecorder").build();
doubleValueRecorder.record(10.1, Labels.empty());
testClock.advanceNanos(50);
testClock.advance(Duration.ofNanos(50));
assertThat(sdkMeterProvider.collectAllMetrics())
.allSatisfy(
@ -291,7 +291,7 @@ public class SdkMeterProviderTest {
"testLongValueRecorder",
"testDoubleValueRecorder");
testClock.advanceNanos(50);
testClock.advance(Duration.ofNanos(50));
longCounter.add(10, Labels.empty());
longUpDownCounter.add(-10, Labels.empty());
@ -484,7 +484,7 @@ public class SdkMeterProviderTest {
.setUpdater(doubleResult -> doubleResult.observe(10.1, Labels.empty()))
.build();
testClock.advanceNanos(50);
testClock.advance(Duration.ofNanos(50));
assertThat(sdkMeterProvider.collectAllMetrics())
.allSatisfy(
@ -514,7 +514,7 @@ public class SdkMeterProviderTest {
"testLongValueObserver",
"testDoubleValueObserver");
testClock.advanceNanos(50);
testClock.advance(Duration.ofNanos(50));
assertThat(sdkMeterProvider.collectAllMetrics())
.allSatisfy(

View File

@ -15,8 +15,8 @@ import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.common.Clock;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link SdkMeterProvider}. */

View File

@ -11,7 +11,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.metrics.aggregator.Aggregator;
import io.opentelemetry.sdk.metrics.aggregator.AggregatorFactory;
import io.opentelemetry.sdk.metrics.aggregator.AggregatorHandle;
@ -22,6 +21,7 @@ import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.processor.LabelsProcessor;
import io.opentelemetry.sdk.metrics.processor.LabelsProcessorFactory;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

View File

@ -0,0 +1,69 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.testing.time;
import io.opentelemetry.api.internal.GuardedBy;
import io.opentelemetry.sdk.common.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import javax.annotation.concurrent.ThreadSafe;
/** A mutable {@link Clock} that allows the time to be set for testing. */
@ThreadSafe
public final class TestClock implements Clock {
@GuardedBy("this")
private long currentEpochNanos;
private TestClock(long epochNanos) {
currentEpochNanos = epochNanos;
}
/**
* Creates a clock initialized to a constant non-zero time.
*
* @return a clock initialized to a constant non-zero time.
*/
public static TestClock create() {
// Set Time to Tuesday, May 7, 2019 12:00:00 AM GMT-07:00 DST
return create(Instant.ofEpochMilli(1_557_212_400_000L));
}
/** Creates a clock with the given time. */
public static TestClock create(Instant instant) {
return new TestClock(toNanos(instant));
}
/** Sets the current time. */
public synchronized void setTime(Instant instant) {
currentEpochNanos = toNanos(instant);
}
/** Advances the time and mutates this instance. */
public synchronized void advance(Duration duration) {
advance(duration.toNanos(), TimeUnit.NANOSECONDS);
}
/** Advances the time and mutates this instance. */
public synchronized void advance(long duration, TimeUnit unit) {
currentEpochNanos += unit.toNanos(duration);
}
@Override
public synchronized long now() {
return currentEpochNanos;
}
@Override
public synchronized long nanoTime() {
return currentEpochNanos;
}
private static long toNanos(Instant instant) {
return TimeUnit.SECONDS.toNanos(instant.getEpochSecond()) + instant.getNano();
}
}

View File

@ -0,0 +1,4 @@
@ParametersAreNonnullByDefault
package io.opentelemetry.sdk.testing.time;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@ -0,0 +1,49 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.testing.time;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
/** Tests for {@link TestClock}. */
public final class TestClockTest {
@Test
void setAndGetTime() {
TestClock clock = TestClock.create(Instant.ofEpochSecond(0, 1234));
assertThat(clock.now()).isEqualTo(1234);
clock.setTime(Instant.ofEpochSecond(0, 9876543210L));
assertThat(clock.now()).isEqualTo(9876543210L);
}
@Test
void advanceDuration() {
TestClock clock = TestClock.create(Instant.ofEpochSecond(0, 1_500_000_000L));
clock.advance(Duration.ofMillis(2600));
assertThat(clock.now()).isEqualTo(4_100_000_000L);
}
@Test
@SuppressWarnings("PreferJavaTimeOverload")
void advanceUnit() {
TestClock clock = TestClock.create(Instant.ofEpochSecond(0, 1_500_000_000L));
clock.advance(2600, TimeUnit.MILLISECONDS);
assertThat(clock.now()).isEqualTo(4_100_000_000L);
}
@Test
void measureElapsedTime() {
TestClock clock = TestClock.create(Instant.ofEpochSecond(0, 10_000_000_001L));
long nanos1 = clock.nanoTime();
clock.setTime(Instant.ofEpochSecond(0, 11_000_000_005L));
long nanos2 = clock.nanoTime();
assertThat(nanos2 - nanos1).isEqualTo(1_000_000_004L);
}
}

View File

@ -8,7 +8,6 @@ package io.opentelemetry.sdk.trace;
import static java.util.Objects.requireNonNull;
import io.opentelemetry.sdk.common.Clock;
import io.opentelemetry.sdk.internal.SystemClock;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.util.ArrayList;
@ -21,7 +20,7 @@ public final class SdkTracerProviderBuilder {
private final List<SpanProcessor> spanProcessors = new ArrayList<>();
private Clock clock = SystemClock.getInstance();
private Clock clock = Clock.getDefault();
private IdGenerator idsGenerator = IdGenerator.random();
private Resource resource = Resource.getDefault();
private Supplier<SpanLimits> spanLimitsSupplier = SpanLimits::getDefault;

View File

@ -27,8 +27,8 @@ import io.opentelemetry.api.trace.TraceFlags;
import io.opentelemetry.api.trace.TraceState;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
import io.opentelemetry.sdk.internal.TestClock;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.time.TestClock;
import io.opentelemetry.sdk.trace.data.EventData;
import io.opentelemetry.sdk.trace.data.LinkData;
import io.opentelemetry.sdk.trace.data.SpanData;
@ -36,6 +36,7 @@ import io.opentelemetry.sdk.trace.data.StatusData;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
@ -61,7 +62,6 @@ class RecordEventsReadableSpanTest {
private static final String SPAN_NAME = "MySpanName";
private static final String SPAN_NEW_NAME = "NewName";
private static final long NANOS_PER_SECOND = TimeUnit.SECONDS.toNanos(1);
private static final long MILLIS_PER_SECOND = TimeUnit.SECONDS.toMillis(1);
private static final long START_EPOCH_NANOS = 1000_123_789_654L;
private final IdGenerator idsGenerator = IdGenerator.random();
@ -91,7 +91,7 @@ class RecordEventsReadableSpanTest {
builder.put(entry.getKey(), entry.getValue());
}
expectedAttributes = builder.build();
testClock = TestClock.create(START_EPOCH_NANOS);
testClock = TestClock.create(Instant.ofEpochSecond(0, START_EPOCH_NANOS));
}
@Test
@ -266,7 +266,7 @@ class RecordEventsReadableSpanTest {
void setStatus() {
RecordEventsReadableSpan span = createTestSpan(SpanKind.CONSUMER);
try {
testClock.advanceMillis(MILLIS_PER_SECOND);
testClock.advance(Duration.ofSeconds(1));
assertThat(span.toSpanData().getStatus()).isEqualTo(StatusData.unset());
span.setStatus(StatusCode.ERROR, "CANCELLED");
assertThat(span.toSpanData().getStatus())
@ -314,10 +314,10 @@ class RecordEventsReadableSpanTest {
void getLatencyNs_ActiveSpan() {
RecordEventsReadableSpan span = createTestSpan(SpanKind.INTERNAL);
try {
testClock.advanceMillis(MILLIS_PER_SECOND);
testClock.advance(Duration.ofSeconds(1));
long elapsedTimeNanos1 = testClock.now() - START_EPOCH_NANOS;
assertThat(span.getLatencyNanos()).isEqualTo(elapsedTimeNanos1);
testClock.advanceMillis(MILLIS_PER_SECOND);
testClock.advance(Duration.ofSeconds(1));
long elapsedTimeNanos2 = testClock.now() - START_EPOCH_NANOS;
assertThat(span.getLatencyNanos()).isEqualTo(elapsedTimeNanos2);
} finally {
@ -328,11 +328,11 @@ class RecordEventsReadableSpanTest {
@Test
void getLatencyNs_EndedSpan() {
RecordEventsReadableSpan span = createTestSpan(SpanKind.INTERNAL);
testClock.advanceMillis(MILLIS_PER_SECOND);
testClock.advance(Duration.ofSeconds(1));
span.end();
long elapsedTimeNanos = testClock.now() - START_EPOCH_NANOS;
assertThat(span.getLatencyNanos()).isEqualTo(elapsedTimeNanos);
testClock.advanceMillis(MILLIS_PER_SECOND);
testClock.advance(Duration.ofSeconds(1));
assertThat(span.getLatencyNanos()).isEqualTo(elapsedTimeNanos);
}
@ -728,7 +728,7 @@ class RecordEventsReadableSpanTest {
try {
for (int i = 0; i < 2 * maxNumberOfEvents; i++) {
span.addEvent("event2", Attributes.empty());
testClock.advanceMillis(MILLIS_PER_SECOND);
testClock.advance(Duration.ofSeconds(1));
}
SpanData spanData = span.toSpanData();
@ -762,7 +762,7 @@ class RecordEventsReadableSpanTest {
exception.printStackTrace(new PrintWriter(writer));
String stacktrace = writer.toString();
testClock.advanceNanos(1000);
testClock.advance(Duration.ofNanos(1000));
long timestamp = testClock.now();
span.recordException(exception);
@ -819,7 +819,7 @@ class RecordEventsReadableSpanTest {
exception.printStackTrace(new PrintWriter(writer));
String stacktrace = writer.toString();
testClock.advanceNanos(1000);
testClock.advance(Duration.ofNanos(1000));
long timestamp = testClock.now();
span.recordException(
@ -944,9 +944,9 @@ class RecordEventsReadableSpanTest {
@Nullable String descriptio) {
span.setAttribute("MySingleStringAttributeKey", "MySingleStringAttributeValue");
attributes.forEach(span::setAttribute);
testClock.advanceMillis(MILLIS_PER_SECOND);
testClock.advance(Duration.ofSeconds(1));
span.addEvent("event2", Attributes.empty());
testClock.advanceMillis(MILLIS_PER_SECOND);
testClock.advance(Duration.ofSeconds(1));
span.updateName(SPAN_NEW_NAME);
if (canonicalCode != null) {
span.setStatus(canonicalCode, descriptio);
@ -1023,14 +1023,14 @@ class RecordEventsReadableSpanTest {
1,
0);
long startEpochNanos = clock.now();
clock.advanceMillis(4);
clock.advance(Duration.ofMillis(4));
long firstEventEpochNanos = clock.now();
readableSpan.addEvent("event1", event1Attributes);
clock.advanceMillis(6);
clock.advance(Duration.ofMillis(6));
long secondEventTimeNanos = clock.now();
readableSpan.addEvent("event2", event2Attributes);
clock.advanceMillis(100);
clock.advance(Duration.ofMillis(100));
readableSpan.end();
long endEpochNanos = clock.now();