-
-
Notifications
You must be signed in to change notification settings - Fork 472
Expand file tree
/
Copy pathComputeNanoStartTimestampForChildTest.kt
More file actions
99 lines (81 loc) · 3.62 KB
/
Copy pathComputeNanoStartTimestampForChildTest.kt
File metadata and controls
99 lines (81 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package io.sentry.sqlite
import io.sentry.DateUtils
import io.sentry.ISpan
import io.sentry.SentryLongDate
import io.sentry.SentryNanotimeDate
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
import kotlin.test.assertTrue
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
class ComputeNanoStartTimestampForChildTest {
@Test
fun `returns parent wall clock plus elapsed monotonic time since parent started`() {
val wallClockMillis = 1_000_000L
val elapsedNanos = 500_000L
val parentMonotonicNanos = System.nanoTime() - elapsedNanos
val span = spanWithNanotimeStart(wallClockMillis, parentMonotonicNanos)
val timestamp = span.computeNanoStartTimestampForChild()!!
val elapsedSinceParentStart = timestamp - DateUtils.millisToNanos(wallClockMillis)
assertTrue(elapsedSinceParentStart >= elapsedNanos)
assertTrue(elapsedSinceParentStart < elapsedNanos + TEST_SLACK_NANOS)
}
@Test
fun `same millisecond wall clocks with different monotonic offsets produce distinct ordered timestamps`() {
val wallClockMillis = 1_000_000L
val wallClockNanos = DateUtils.millisToNanos(wallClockMillis)
val earlierParentMonotonicNanos = System.nanoTime() - 200_000L
val laterParentMonotonicNanos = System.nanoTime() - 800_000L
val earlierSpan = spanWithNanotimeStart(wallClockMillis, earlierParentMonotonicNanos)
val laterSpan = spanWithNanotimeStart(wallClockMillis, laterParentMonotonicNanos)
assertEquals(
earlierSpan.startDate.nanoTimestamp(),
laterSpan.startDate.nanoTimestamp(),
"Raw parent timestamps share the same ms-quantized value",
)
val earlier = earlierSpan.computeNanoStartTimestampForChild()!!
val later = laterSpan.computeNanoStartTimestampForChild()!!
assertTrue(earlier > wallClockNanos)
assertTrue(later > wallClockNanos)
assertTrue(earlier < later)
assertTrue(later - earlier >= 500_000L)
}
@Test
fun `returns parent wall clock when no monotonic time has elapsed since parent started`() {
val wallClockMillis = 1_000_000L
val parentMonotonicNanos = System.nanoTime()
val span = spanWithNanotimeStart(wallClockMillis, parentMonotonicNanos)
val elapsedSinceParentStart =
span.computeNanoStartTimestampForChild()!! - DateUtils.millisToNanos(wallClockMillis)
assertTrue(elapsedSinceParentStart >= 0L)
assertTrue(elapsedSinceParentStart < TEST_SLACK_NANOS)
}
@Test
fun `works when parent wall clock differs from millisecond baseline`() {
val wallClockMillis = 1_000_001L
val elapsedNanos = 1_500_000L
val parentMonotonicNanos = System.nanoTime() - elapsedNanos
val span = spanWithNanotimeStart(wallClockMillis, parentMonotonicNanos)
val elapsedSinceParentStart =
span.computeNanoStartTimestampForChild()!! - DateUtils.millisToNanos(wallClockMillis)
assertTrue(elapsedSinceParentStart >= elapsedNanos)
assertTrue(elapsedSinceParentStart < elapsedNanos + TEST_SLACK_NANOS)
}
@Test
fun `returns null when start date is not SentryNanotimeDate`() {
val span = mock<ISpan>()
whenever(span.startDate).thenReturn(SentryLongDate(DateUtils.millisToNanos(1_000_000L)))
assertNull(span.computeNanoStartTimestampForChild())
}
private fun spanWithNanotimeStart(wallClockMillis: Long, parentMonotonicNanos: Long): ISpan {
val startDate = SentryNanotimeDate(wallClockMillis, parentMonotonicNanos)
val span = mock<ISpan>()
whenever(span.startDate).thenReturn(startDate)
return span
}
companion object {
// Upper bound for monotonic drift while the test body runs.
private const val TEST_SLACK_NANOS = 50_000_000L
}
}