Change clock and converter to use epoch nanos (#636)
Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>
This commit is contained in:
parent
ab00d64b4c
commit
bd14f39727
|
|
@ -35,7 +35,8 @@ public abstract class Timestamp {
|
||||||
private static final long MAX_SECONDS = 315576000000L;
|
private static final long MAX_SECONDS = 315576000000L;
|
||||||
private static final int MAX_NANOS = 999999999;
|
private static final int MAX_NANOS = 999999999;
|
||||||
private static final long MILLIS_PER_SECOND = 1000L;
|
private static final long MILLIS_PER_SECOND = 1000L;
|
||||||
private static final long NANOS_PER_MILLI = 1000 * 1000;
|
private static final long NANOS_PER_SECOND = 1000L * 1000L * 1000L;
|
||||||
|
private static final long NANOS_PER_MILLI = 1000L * 1000L;
|
||||||
|
|
||||||
Timestamp() {}
|
Timestamp() {}
|
||||||
|
|
||||||
|
|
@ -85,6 +86,21 @@ public abstract class Timestamp {
|
||||||
return create(secs, (int) (mos * NANOS_PER_MILLI)); // Safe int * NANOS_PER_MILLI
|
return create(secs, (int) (mos * NANOS_PER_MILLI)); // Safe int * NANOS_PER_MILLI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new timestamp from the given milliseconds.
|
||||||
|
*
|
||||||
|
* @param epochNanos the timestamp represented in nanoseconds since epoch.
|
||||||
|
* @return new {@code Timestamp} with specified fields.
|
||||||
|
* @throws IllegalArgumentException if the number of milliseconds is out of the range that can be
|
||||||
|
* represented by {@code Timestamp}.
|
||||||
|
* @since 0.1.0
|
||||||
|
*/
|
||||||
|
public static Timestamp fromNanos(long epochNanos) {
|
||||||
|
long secs = floorDiv(epochNanos, NANOS_PER_SECOND);
|
||||||
|
int nanos = (int) floorMod(epochNanos, NANOS_PER_SECOND);
|
||||||
|
return create(secs, nanos); // Safe int * NANOS_PER_MILLI
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of seconds since the Unix Epoch represented by this timestamp.
|
* Returns the number of seconds since the Unix Epoch represented by this timestamp.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
package io.opentelemetry.sdk.internal;
|
package io.opentelemetry.sdk.internal;
|
||||||
|
|
||||||
import io.opentelemetry.sdk.common.Timestamp;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for getting the current time.
|
* Interface for getting the current time.
|
||||||
*
|
*
|
||||||
|
|
@ -25,12 +23,12 @@ import io.opentelemetry.sdk.common.Timestamp;
|
||||||
*/
|
*/
|
||||||
public interface Clock {
|
public interface Clock {
|
||||||
/**
|
/**
|
||||||
* Obtains the current instant from this clock.
|
* Obtains the current epoch timestamp in nanos from this clock.
|
||||||
*
|
*
|
||||||
* @return the current instant.
|
* @return the current epoch timestamp in nanos.
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
Timestamp now();
|
long now();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a time measurement with nanosecond precision that can only be used to calculate elapsed
|
* Returns a time measurement with nanosecond precision that can only be used to calculate elapsed
|
||||||
|
|
@ -40,5 +38,5 @@ public interface Clock {
|
||||||
* time.
|
* time.
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
long nowNanos();
|
long nanoTime();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
package io.opentelemetry.sdk.internal;
|
package io.opentelemetry.sdk.internal;
|
||||||
|
|
||||||
import io.opentelemetry.sdk.common.Timestamp;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
/** A {@link Clock} that uses {@link System#currentTimeMillis()} and {@link System#nanoTime()}. */
|
/** A {@link Clock} that uses {@link System#currentTimeMillis()} and {@link System#nanoTime()}. */
|
||||||
|
|
@ -37,12 +37,12 @@ public final class MillisClock implements Clock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Timestamp now() {
|
public long now() {
|
||||||
return Timestamp.fromMillis(System.currentTimeMillis());
|
return TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long nowNanos() {
|
public long nanoTime() {
|
||||||
return System.nanoTime();
|
return System.nanoTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,8 @@
|
||||||
package io.opentelemetry.sdk.internal;
|
package io.opentelemetry.sdk.internal;
|
||||||
|
|
||||||
import static io.opentelemetry.sdk.internal.TimestampConverter.NANOS_PER_MILLI;
|
import static io.opentelemetry.sdk.internal.TimestampConverter.NANOS_PER_MILLI;
|
||||||
import static io.opentelemetry.sdk.internal.TimestampConverter.NANOS_PER_SECOND;
|
|
||||||
|
|
||||||
import io.opentelemetry.sdk.common.Timestamp;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
|
|
@ -32,10 +31,10 @@ import javax.annotation.concurrent.ThreadSafe;
|
||||||
public class TestClock implements Clock {
|
public class TestClock implements Clock {
|
||||||
|
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private Timestamp currentTimestamp;
|
private long currentEpochNanos;
|
||||||
|
|
||||||
private TestClock(Timestamp timestamp) {
|
private TestClock(long epochNanos) {
|
||||||
currentTimestamp = timestamp;
|
currentEpochNanos = epochNanos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -46,28 +45,28 @@ public class TestClock implements Clock {
|
||||||
*/
|
*/
|
||||||
public static TestClock create() {
|
public static TestClock create() {
|
||||||
// Set Time to Tuesday, May 7, 2019 12:00:00 AM GMT-07:00 DST
|
// Set Time to Tuesday, May 7, 2019 12:00:00 AM GMT-07:00 DST
|
||||||
return create(Timestamp.fromMillis(1_557_212_400_000L));
|
return create(TimeUnit.MILLISECONDS.toNanos(1_557_212_400_000L));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a clock with the given time.
|
* Creates a clock with the given time.
|
||||||
*
|
*
|
||||||
* @param timestamp the initial time.
|
* @param epochNanos the initial time in nanos since epoch.
|
||||||
* @return a new {@code TestClock} with the given time.
|
* @return a new {@code TestClock} with the given time.
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
public static TestClock create(Timestamp timestamp) {
|
public static TestClock create(long epochNanos) {
|
||||||
return new TestClock(timestamp);
|
return new TestClock(epochNanos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the time.
|
* Sets the time.
|
||||||
*
|
*
|
||||||
* @param timestamp the new time.
|
* @param epochNanos the new time.
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
public synchronized void setTime(Timestamp timestamp) {
|
public synchronized void setTime(long epochNanos) {
|
||||||
currentTimestamp = timestamp;
|
currentEpochNanos = epochNanos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -77,27 +76,17 @@ public class TestClock implements Clock {
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
public synchronized void advanceMillis(long millis) {
|
public synchronized void advanceMillis(long millis) {
|
||||||
long incomingSeconds = millis / 1000;
|
long nanos = millis * NANOS_PER_MILLI;
|
||||||
long remainingMillis = millis % 1000;
|
currentEpochNanos += nanos;
|
||||||
long remainingNanos = remainingMillis * NANOS_PER_MILLI;
|
|
||||||
|
|
||||||
long newSeconds = incomingSeconds + currentTimestamp.getSeconds();
|
|
||||||
long newNanos = remainingNanos + currentTimestamp.getNanos();
|
|
||||||
|
|
||||||
if (newNanos >= NANOS_PER_SECOND) {
|
|
||||||
newSeconds += newNanos / NANOS_PER_SECOND;
|
|
||||||
newNanos = newNanos % NANOS_PER_SECOND;
|
|
||||||
}
|
|
||||||
currentTimestamp = Timestamp.create(newSeconds, (int) newNanos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized Timestamp now() {
|
public synchronized long now() {
|
||||||
return currentTimestamp;
|
return currentEpochNanos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized long nowNanos() {
|
public synchronized long nanoTime() {
|
||||||
return (currentTimestamp.getSeconds() * NANOS_PER_SECOND) + currentTimestamp.getNanos();
|
return currentEpochNanos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ public class TimestampConverter {
|
||||||
static final long NANOS_PER_SECOND = 1_000_000_000;
|
static final long NANOS_PER_SECOND = 1_000_000_000;
|
||||||
static final long NANOS_PER_MILLI = 1_000_000;
|
static final long NANOS_PER_MILLI = 1_000_000;
|
||||||
|
|
||||||
private final Timestamp timestamp;
|
private final long epochNanos;
|
||||||
private final long nanoTime;
|
private final long nanoTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -39,7 +39,7 @@ public class TimestampConverter {
|
||||||
* @return a {@code TimestampConverter} initialized to now.
|
* @return a {@code TimestampConverter} initialized to now.
|
||||||
*/
|
*/
|
||||||
public static TimestampConverter now(Clock clock) {
|
public static TimestampConverter now(Clock clock) {
|
||||||
return new TimestampConverter(clock.now(), clock.nowNanos());
|
return new TimestampConverter(clock.now(), clock.nanoTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -48,21 +48,13 @@ public class TimestampConverter {
|
||||||
* @param nanoTime value to convert.
|
* @param nanoTime value to convert.
|
||||||
* @return the {@code Timestamp} representation of the {@code time}.
|
* @return the {@code Timestamp} representation of the {@code time}.
|
||||||
*/
|
*/
|
||||||
public Timestamp convertNanoTime(long nanoTime) {
|
public long convertNanoTime(long nanoTime) {
|
||||||
long deltaNanos = nanoTime - this.nanoTime;
|
long deltaNanos = nanoTime - this.nanoTime;
|
||||||
|
return epochNanos + deltaNanos;
|
||||||
long seconds = timestamp.getSeconds() + (deltaNanos / NANOS_PER_SECOND);
|
|
||||||
long nanos = timestamp.getNanos() + (deltaNanos % NANOS_PER_SECOND);
|
|
||||||
|
|
||||||
if (nanos >= NANOS_PER_SECOND) {
|
|
||||||
seconds += nanos / NANOS_PER_SECOND;
|
|
||||||
nanos = nanos % NANOS_PER_SECOND;
|
|
||||||
}
|
|
||||||
return Timestamp.create(seconds, (int) nanos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimestampConverter(Timestamp timestamp, long nanoTime) {
|
private TimestampConverter(long epochNanos, long nanoTime) {
|
||||||
this.timestamp = timestamp;
|
this.epochNanos = epochNanos;
|
||||||
this.nanoTime = nanoTime;
|
this.nanoTime = nanoTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,8 +156,10 @@ final class RecordEventsReadableSpan implements ReadableSpan, Span {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpanData toSpanData() {
|
public SpanData toSpanData() {
|
||||||
Timestamp startTimestamp = timestampConverter.convertNanoTime(startNanoTime);
|
Timestamp startTimestamp =
|
||||||
Timestamp endTimestamp = timestampConverter.convertNanoTime(getEndNanoTime());
|
Timestamp.fromNanos(timestampConverter.convertNanoTime(startNanoTime));
|
||||||
|
Timestamp endTimestamp =
|
||||||
|
Timestamp.fromNanos(timestampConverter.convertNanoTime(getEndNanoTime()));
|
||||||
SpanContext spanContext = getSpanContext();
|
SpanContext spanContext = getSpanContext();
|
||||||
return SpanData.newBuilder()
|
return SpanData.newBuilder()
|
||||||
.setName(getName())
|
.setName(getName())
|
||||||
|
|
@ -188,7 +190,8 @@ final class RecordEventsReadableSpan implements ReadableSpan, Span {
|
||||||
|
|
||||||
private static SpanData.TimedEvent adaptTimedEvent(
|
private static SpanData.TimedEvent adaptTimedEvent(
|
||||||
io.opentelemetry.sdk.trace.TimedEvent sourceEvent, TimestampConverter timestampConverter) {
|
io.opentelemetry.sdk.trace.TimedEvent sourceEvent, TimestampConverter timestampConverter) {
|
||||||
Timestamp timestamp = timestampConverter.convertNanoTime(sourceEvent.getNanotime());
|
Timestamp timestamp =
|
||||||
|
Timestamp.fromNanos(timestampConverter.convertNanoTime(sourceEvent.getNanotime()));
|
||||||
return SpanData.TimedEvent.create(
|
return SpanData.TimedEvent.create(
|
||||||
timestamp, sourceEvent.getName(), sourceEvent.getAttributes());
|
timestamp, sourceEvent.getName(), sourceEvent.getAttributes());
|
||||||
}
|
}
|
||||||
|
|
@ -212,7 +215,7 @@ final class RecordEventsReadableSpan implements ReadableSpan, Span {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the end nano time (see {@link System#nanoTime()}). If the current {@code Span} is not
|
* Returns the end nano time (see {@link System#nanoTime()}). If the current {@code Span} is not
|
||||||
* ended then returns {@link Clock#nowNanos()}.
|
* ended then returns {@link Clock#nanoTime()}.
|
||||||
*
|
*
|
||||||
* @return the end nano time.
|
* @return the end nano time.
|
||||||
*/
|
*/
|
||||||
|
|
@ -297,7 +300,7 @@ final class RecordEventsReadableSpan implements ReadableSpan, Span {
|
||||||
// Use getEndNanoTimeInternal to avoid over-locking.
|
// Use getEndNanoTimeInternal to avoid over-locking.
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private long getEndNanoTimeInternal() {
|
private long getEndNanoTimeInternal() {
|
||||||
return hasBeenEnded ? endNanoTime : clock.nowNanos();
|
return hasBeenEnded ? endNanoTime : clock.nanoTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -365,35 +368,35 @@ final class RecordEventsReadableSpan implements ReadableSpan, Span {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEvent(String name) {
|
public void addEvent(String name) {
|
||||||
addTimedEvent(TimedEvent.create(clock.nowNanos(), name));
|
addTimedEvent(TimedEvent.create(clock.nanoTime(), name));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use timestamp.
|
// TODO: Use timestamp.
|
||||||
@Override
|
@Override
|
||||||
public void addEvent(String name, long timestamp) {
|
public void addEvent(String name, long timestamp) {
|
||||||
addTimedEvent(TimedEvent.create(clock.nowNanos(), name));
|
addTimedEvent(TimedEvent.create(clock.nanoTime(), name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEvent(String name, Map<String, AttributeValue> attributes) {
|
public void addEvent(String name, Map<String, AttributeValue> attributes) {
|
||||||
addTimedEvent(TimedEvent.create(clock.nowNanos(), name, attributes));
|
addTimedEvent(TimedEvent.create(clock.nanoTime(), name, attributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use timestamp.
|
// TODO: Use timestamp.
|
||||||
@Override
|
@Override
|
||||||
public void addEvent(String name, Map<String, AttributeValue> attributes, long timestamp) {
|
public void addEvent(String name, Map<String, AttributeValue> attributes, long timestamp) {
|
||||||
addTimedEvent(TimedEvent.create(clock.nowNanos(), name, attributes));
|
addTimedEvent(TimedEvent.create(clock.nanoTime(), name, attributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEvent(Event event) {
|
public void addEvent(Event event) {
|
||||||
addTimedEvent(TimedEvent.create(clock.nowNanos(), event));
|
addTimedEvent(TimedEvent.create(clock.nanoTime(), event));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use timestamp.
|
// TODO: Use timestamp.
|
||||||
@Override
|
@Override
|
||||||
public void addEvent(Event event, long timestamp) {
|
public void addEvent(Event event, long timestamp) {
|
||||||
addTimedEvent(TimedEvent.create(clock.nowNanos(), event));
|
addTimedEvent(TimedEvent.create(clock.nanoTime(), event));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addTimedEvent(TimedEvent timedEvent) {
|
private void addTimedEvent(TimedEvent timedEvent) {
|
||||||
|
|
@ -438,7 +441,7 @@ final class RecordEventsReadableSpan implements ReadableSpan, Span {
|
||||||
logger.log(Level.FINE, "Calling end() on an ended Span.");
|
logger.log(Level.FINE, "Calling end() on an ended Span.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
endNanoTime = clock.nowNanos();
|
endNanoTime = clock.nanoTime();
|
||||||
hasBeenEnded = true;
|
hasBeenEnded = true;
|
||||||
}
|
}
|
||||||
spanProcessor.onEnd(this);
|
spanProcessor.onEnd(this);
|
||||||
|
|
@ -555,7 +558,7 @@ final class RecordEventsReadableSpan implements ReadableSpan, Span {
|
||||||
this.numberOfChildren = 0;
|
this.numberOfChildren = 0;
|
||||||
this.timestampConverter =
|
this.timestampConverter =
|
||||||
timestampConverter != null ? timestampConverter : TimestampConverter.now(clock);
|
timestampConverter != null ? timestampConverter : TimestampConverter.now(clock);
|
||||||
startNanoTime = clock.nowNanos();
|
startNanoTime = clock.nanoTime();
|
||||||
if (!attributes.isEmpty()) {
|
if (!attributes.isEmpty()) {
|
||||||
getInitializedAttributes().putAll(attributes);
|
getInitializedAttributes().putAll(attributes);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2019, OpenTelemetry Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.sdk.internal;
|
|
||||||
|
|
||||||
import io.opentelemetry.sdk.common.Timestamp;
|
|
||||||
|
|
||||||
final class ClockTestUtil {
|
|
||||||
static final int NANOS_PER_SECOND = 1000 * 1000 * 1000;
|
|
||||||
static final int NANOS_PER_MILLI = 1000 * 1000;
|
|
||||||
|
|
||||||
static Timestamp createTimestamp(long seconds, int nanos) {
|
|
||||||
return Timestamp.create(seconds, nanos);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClockTestUtil() {}
|
|
||||||
}
|
|
||||||
|
|
@ -28,27 +28,25 @@ public final class TestClockTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setAndGetTime() {
|
public void setAndGetTime() {
|
||||||
TestClock clock = TestClock.create(ClockTestUtil.createTimestamp(1, 2));
|
TestClock clock = TestClock.create(1234);
|
||||||
assertThat(clock.now()).isEqualTo(ClockTestUtil.createTimestamp(1, 2));
|
assertThat(clock.now()).isEqualTo(1234);
|
||||||
clock.setTime(ClockTestUtil.createTimestamp(3, 4));
|
clock.setTime(9876543210L);
|
||||||
assertThat(clock.now()).isEqualTo(ClockTestUtil.createTimestamp(3, 4));
|
assertThat(clock.now()).isEqualTo(9876543210L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void advanceMillis() {
|
public void advanceMillis() {
|
||||||
TestClock clock =
|
TestClock clock = TestClock.create(1_500_000_000L);
|
||||||
TestClock.create(ClockTestUtil.createTimestamp(1, 500 * ClockTestUtil.NANOS_PER_MILLI));
|
|
||||||
clock.advanceMillis(2600);
|
clock.advanceMillis(2600);
|
||||||
assertThat(clock.now())
|
assertThat(clock.now()).isEqualTo(4_100_000_000L);
|
||||||
.isEqualTo(ClockTestUtil.createTimestamp(4, 100 * ClockTestUtil.NANOS_PER_MILLI));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void measureElapsedTime() {
|
public void measureElapsedTime() {
|
||||||
TestClock clock = TestClock.create(ClockTestUtil.createTimestamp(10, 1));
|
TestClock clock = TestClock.create(10_000_000_001L);
|
||||||
long nanos1 = clock.nowNanos();
|
long nanos1 = clock.nanoTime();
|
||||||
clock.setTime(ClockTestUtil.createTimestamp(11, 5));
|
clock.setTime(11_000_000_005L);
|
||||||
long nanos2 = clock.nowNanos();
|
long nanos2 = clock.nanoTime();
|
||||||
assertThat(nanos2 - nanos1).isEqualTo(ClockTestUtil.NANOS_PER_SECOND + 4);
|
assertThat(nanos2 - nanos1).isEqualTo(1_000_000_004L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,7 @@
|
||||||
package io.opentelemetry.sdk.internal;
|
package io.opentelemetry.sdk.internal;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static io.opentelemetry.sdk.internal.ClockTestUtil.createTimestamp;
|
|
||||||
|
|
||||||
import io.opentelemetry.sdk.common.Timestamp;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
|
|
@ -27,35 +25,35 @@ import org.junit.runners.JUnit4;
|
||||||
/** Unit tests for {@link TimestampConverter}. */
|
/** Unit tests for {@link TimestampConverter}. */
|
||||||
@RunWith(JUnit4.class)
|
@RunWith(JUnit4.class)
|
||||||
public class TimestampConverterTest {
|
public class TimestampConverterTest {
|
||||||
private final Timestamp timestamp = createTimestamp(1234, 5678);
|
private final long epochNanos = 1234_000_005_678L;
|
||||||
private final TestClock testClock = TestClock.create(timestamp);
|
private final TestClock testClock = TestClock.create(epochNanos);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void now() {
|
public void now() {
|
||||||
assertThat(testClock.now()).isEqualTo(timestamp);
|
assertThat(testClock.now()).isEqualTo(epochNanos);
|
||||||
TimestampConverter timeConverter = TimestampConverter.now(testClock);
|
TimestampConverter timeConverter = TimestampConverter.now(testClock);
|
||||||
assertThat(timeConverter.convertNanoTime(testClock.nowNanos())).isEqualTo(timestamp);
|
assertThat(timeConverter.convertNanoTime(testClock.nanoTime())).isEqualTo(epochNanos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void convertNanoTime_Positive() {
|
public void convertNanoTime_Positive() {
|
||||||
TimestampConverter timeConverter = TimestampConverter.now(testClock);
|
TimestampConverter timeConverter = TimestampConverter.now(testClock);
|
||||||
assertThat(timeConverter.convertNanoTime(testClock.nowNanos() + 3210))
|
assertThat(timeConverter.convertNanoTime(testClock.nanoTime() + 3210))
|
||||||
.isEqualTo(createTimestamp(1234, 8888));
|
.isEqualTo(1234_000_008_888L);
|
||||||
assertThat(timeConverter.convertNanoTime(testClock.nowNanos() + 1000))
|
assertThat(timeConverter.convertNanoTime(testClock.nanoTime() + 1000))
|
||||||
.isEqualTo(createTimestamp(1234, 6678));
|
.isEqualTo(1234_000_006_678L);
|
||||||
assertThat(timeConverter.convertNanoTime(testClock.nowNanos() + 15_999_994_322L))
|
assertThat(timeConverter.convertNanoTime(testClock.nanoTime() + 15_999_994_322L))
|
||||||
.isEqualTo(createTimestamp(1250, 0));
|
.isEqualTo(1250_000_000_000L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void convertNanoTime_Negative() {
|
public void convertNanoTime_Negative() {
|
||||||
TimestampConverter timeConverter = TimestampConverter.now(testClock);
|
TimestampConverter timeConverter = TimestampConverter.now(testClock);
|
||||||
assertThat(timeConverter.convertNanoTime(testClock.nowNanos() - 3456))
|
assertThat(timeConverter.convertNanoTime(testClock.nanoTime() - 3456))
|
||||||
.isEqualTo(createTimestamp(1234, 2222));
|
.isEqualTo(1234_000_002_222L);
|
||||||
assertThat(timeConverter.convertNanoTime(testClock.nowNanos() - 1000))
|
assertThat(timeConverter.convertNanoTime(testClock.nanoTime() - 1000))
|
||||||
.isEqualTo(createTimestamp(1234, 4678));
|
.isEqualTo(1234_000_004_678L);
|
||||||
assertThat(timeConverter.convertNanoTime(testClock.nowNanos() - 14000005678L))
|
assertThat(timeConverter.convertNanoTime(testClock.nanoTime() - 14000005678L))
|
||||||
.isEqualTo(createTimestamp(1220, 0));
|
.isEqualTo(1220_000_000_000L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,8 @@ public class RecordEventsReadableSpanTest {
|
||||||
private final SpanId parentSpanId = TestUtils.generateRandomSpanId();
|
private final SpanId parentSpanId = TestUtils.generateRandomSpanId();
|
||||||
private final SpanContext spanContext =
|
private final SpanContext spanContext =
|
||||||
SpanContext.create(traceId, spanId, TraceFlags.getDefault(), Tracestate.getDefault());
|
SpanContext.create(traceId, spanId, TraceFlags.getDefault(), Tracestate.getDefault());
|
||||||
private final Timestamp startTime = Timestamp.create(1000, 0);
|
private final long startEpochNanos = 1000_123_789_654L;
|
||||||
private final TestClock testClock = TestClock.create(startTime);
|
private final TestClock testClock = TestClock.create(startEpochNanos);
|
||||||
private final TimestampConverter timestampConverter = TimestampConverter.now(testClock);
|
private final TimestampConverter timestampConverter = TimestampConverter.now(testClock);
|
||||||
private final Resource resource = Resource.getEmpty();
|
private final Resource resource = Resource.getEmpty();
|
||||||
private final Map<String, AttributeValue> attributes = new HashMap<>();
|
private final Map<String, AttributeValue> attributes = new HashMap<>();
|
||||||
|
|
@ -101,8 +101,8 @@ public class RecordEventsReadableSpanTest {
|
||||||
Collections.<SpanData.TimedEvent>emptyList(),
|
Collections.<SpanData.TimedEvent>emptyList(),
|
||||||
Collections.singletonList(link),
|
Collections.singletonList(link),
|
||||||
SPAN_NAME,
|
SPAN_NAME,
|
||||||
Timestamp.create(startTime.getSeconds(), 0),
|
Timestamp.fromNanos(startEpochNanos),
|
||||||
Timestamp.create(startTime.getSeconds(), 0),
|
Timestamp.fromNanos(startEpochNanos),
|
||||||
Status.OK);
|
Status.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,7 +121,7 @@ public class RecordEventsReadableSpanTest {
|
||||||
SpanData spanData = span.toSpanData();
|
SpanData spanData = span.toSpanData();
|
||||||
SpanData.TimedEvent timedEvent =
|
SpanData.TimedEvent timedEvent =
|
||||||
SpanData.TimedEvent.create(
|
SpanData.TimedEvent.create(
|
||||||
Timestamp.create(startTime.getSeconds() + 1, 0),
|
Timestamp.fromNanos(startEpochNanos + NANOS_PER_SECOND),
|
||||||
"event2",
|
"event2",
|
||||||
Collections.<String, AttributeValue>emptyMap());
|
Collections.<String, AttributeValue>emptyMap());
|
||||||
verifySpanData(
|
verifySpanData(
|
||||||
|
|
@ -130,8 +130,8 @@ public class RecordEventsReadableSpanTest {
|
||||||
Collections.singletonList(timedEvent),
|
Collections.singletonList(timedEvent),
|
||||||
Collections.singletonList(link),
|
Collections.singletonList(link),
|
||||||
SPAN_NEW_NAME,
|
SPAN_NEW_NAME,
|
||||||
Timestamp.create(startTime.getSeconds(), 0),
|
Timestamp.fromNanos(startEpochNanos),
|
||||||
Timestamp.create(testClock.now().getSeconds(), 0),
|
Timestamp.fromNanos(testClock.now()),
|
||||||
Status.OK);
|
Status.OK);
|
||||||
} finally {
|
} finally {
|
||||||
span.end();
|
span.end();
|
||||||
|
|
@ -150,7 +150,7 @@ public class RecordEventsReadableSpanTest {
|
||||||
SpanData spanData = span.toSpanData();
|
SpanData spanData = span.toSpanData();
|
||||||
SpanData.TimedEvent timedEvent =
|
SpanData.TimedEvent timedEvent =
|
||||||
SpanData.TimedEvent.create(
|
SpanData.TimedEvent.create(
|
||||||
Timestamp.create(startTime.getSeconds() + 1, 0),
|
Timestamp.fromNanos(startEpochNanos + NANOS_PER_SECOND),
|
||||||
"event2",
|
"event2",
|
||||||
Collections.<String, AttributeValue>emptyMap());
|
Collections.<String, AttributeValue>emptyMap());
|
||||||
verifySpanData(
|
verifySpanData(
|
||||||
|
|
@ -159,8 +159,8 @@ public class RecordEventsReadableSpanTest {
|
||||||
Collections.singletonList(timedEvent),
|
Collections.singletonList(timedEvent),
|
||||||
Collections.singletonList(link),
|
Collections.singletonList(link),
|
||||||
SPAN_NEW_NAME,
|
SPAN_NEW_NAME,
|
||||||
Timestamp.create(startTime.getSeconds(), 0),
|
Timestamp.fromNanos(startEpochNanos),
|
||||||
Timestamp.create(testClock.now().getSeconds(), 0),
|
Timestamp.fromNanos(testClock.now()),
|
||||||
Status.CANCELLED);
|
Status.CANCELLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,12 +225,10 @@ public class RecordEventsReadableSpanTest {
|
||||||
RecordEventsReadableSpan span = createTestSpan(Kind.INTERNAL);
|
RecordEventsReadableSpan span = createTestSpan(Kind.INTERNAL);
|
||||||
try {
|
try {
|
||||||
testClock.advanceMillis(MILLIS_PER_SECOND);
|
testClock.advanceMillis(MILLIS_PER_SECOND);
|
||||||
long elapsedTimeNanos1 =
|
long elapsedTimeNanos1 = testClock.now() - startEpochNanos;
|
||||||
(testClock.now().getSeconds() - startTime.getSeconds()) * NANOS_PER_SECOND;
|
|
||||||
assertThat(span.getLatencyNs()).isEqualTo(elapsedTimeNanos1);
|
assertThat(span.getLatencyNs()).isEqualTo(elapsedTimeNanos1);
|
||||||
testClock.advanceMillis(MILLIS_PER_SECOND);
|
testClock.advanceMillis(MILLIS_PER_SECOND);
|
||||||
long elapsedTimeNanos2 =
|
long elapsedTimeNanos2 = testClock.now() - startEpochNanos;
|
||||||
(testClock.now().getSeconds() - startTime.getSeconds()) * NANOS_PER_SECOND;
|
|
||||||
assertThat(span.getLatencyNs()).isEqualTo(elapsedTimeNanos2);
|
assertThat(span.getLatencyNs()).isEqualTo(elapsedTimeNanos2);
|
||||||
} finally {
|
} finally {
|
||||||
span.end();
|
span.end();
|
||||||
|
|
@ -242,8 +240,7 @@ public class RecordEventsReadableSpanTest {
|
||||||
RecordEventsReadableSpan span = createTestSpan(Kind.INTERNAL);
|
RecordEventsReadableSpan span = createTestSpan(Kind.INTERNAL);
|
||||||
testClock.advanceMillis(MILLIS_PER_SECOND);
|
testClock.advanceMillis(MILLIS_PER_SECOND);
|
||||||
span.end();
|
span.end();
|
||||||
long elapsedTimeNanos =
|
long elapsedTimeNanos = testClock.now() - startEpochNanos;
|
||||||
(testClock.now().getSeconds() - startTime.getSeconds()) * NANOS_PER_SECOND;
|
|
||||||
assertThat(span.getLatencyNs()).isEqualTo(elapsedTimeNanos);
|
assertThat(span.getLatencyNs()).isEqualTo(elapsedTimeNanos);
|
||||||
testClock.advanceMillis(MILLIS_PER_SECOND);
|
testClock.advanceMillis(MILLIS_PER_SECOND);
|
||||||
assertThat(span.getLatencyNs()).isEqualTo(elapsedTimeNanos);
|
assertThat(span.getLatencyNs()).isEqualTo(elapsedTimeNanos);
|
||||||
|
|
@ -384,7 +381,7 @@ public class RecordEventsReadableSpanTest {
|
||||||
for (int i = 0; i < maxNumberOfEvents; i++) {
|
for (int i = 0; i < maxNumberOfEvents; i++) {
|
||||||
SpanData.TimedEvent expectedEvent =
|
SpanData.TimedEvent expectedEvent =
|
||||||
SpanData.TimedEvent.create(
|
SpanData.TimedEvent.create(
|
||||||
Timestamp.create(startTime.getSeconds() + maxNumberOfEvents + i, 0),
|
Timestamp.fromNanos(startEpochNanos + (maxNumberOfEvents + i) * NANOS_PER_SECOND),
|
||||||
"event2",
|
"event2",
|
||||||
Collections.<String, AttributeValue>emptyMap());
|
Collections.<String, AttributeValue>emptyMap());
|
||||||
assertThat(spanData.getTimedEvents().get(i)).isEqualTo(expectedEvent);
|
assertThat(spanData.getTimedEvents().get(i)).isEqualTo(expectedEvent);
|
||||||
|
|
@ -397,7 +394,7 @@ public class RecordEventsReadableSpanTest {
|
||||||
for (int i = 0; i < maxNumberOfEvents; i++) {
|
for (int i = 0; i < maxNumberOfEvents; i++) {
|
||||||
SpanData.TimedEvent expectedEvent =
|
SpanData.TimedEvent expectedEvent =
|
||||||
SpanData.TimedEvent.create(
|
SpanData.TimedEvent.create(
|
||||||
Timestamp.create(startTime.getSeconds() + maxNumberOfEvents + i, 0),
|
Timestamp.fromNanos(startEpochNanos + (maxNumberOfEvents + i) * NANOS_PER_SECOND),
|
||||||
"event2",
|
"event2",
|
||||||
Collections.<String, AttributeValue>emptyMap());
|
Collections.<String, AttributeValue>emptyMap());
|
||||||
assertThat(spanData.getTimedEvents().get(i)).isEqualTo(expectedEvent);
|
assertThat(spanData.getTimedEvents().get(i)).isEqualTo(expectedEvent);
|
||||||
|
|
@ -528,17 +525,17 @@ public class RecordEventsReadableSpanTest {
|
||||||
attributes,
|
attributes,
|
||||||
links,
|
links,
|
||||||
1);
|
1);
|
||||||
long startTimeNanos = clock.nowNanos();
|
long startTimeNanos = clock.nanoTime();
|
||||||
clock.advanceMillis(4);
|
clock.advanceMillis(4);
|
||||||
long firstEventTimeNanos = clock.nowNanos();
|
long firstEventTimeNanos = clock.nanoTime();
|
||||||
readableSpan.addEvent("event1", event1Attributes);
|
readableSpan.addEvent("event1", event1Attributes);
|
||||||
clock.advanceMillis(6);
|
clock.advanceMillis(6);
|
||||||
long secondEventTimeNanos = clock.nowNanos();
|
long secondEventTimeNanos = clock.nanoTime();
|
||||||
readableSpan.addEvent("event2", event2Attributes);
|
readableSpan.addEvent("event2", event2Attributes);
|
||||||
|
|
||||||
clock.advanceMillis(100);
|
clock.advanceMillis(100);
|
||||||
readableSpan.end();
|
readableSpan.end();
|
||||||
long endTimeNanos = clock.nowNanos();
|
long endTimeNanos = clock.nanoTime();
|
||||||
|
|
||||||
SpanData expected =
|
SpanData expected =
|
||||||
SpanData.newBuilder()
|
SpanData.newBuilder()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue