-
-
Notifications
You must be signed in to change notification settings - Fork 426
/
SentryTransactionAdviceTest.kt
163 lines (133 loc) · 5.53 KB
/
SentryTransactionAdviceTest.kt
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package io.sentry.spring.tracing
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.check
import com.nhaarman.mockitokotlin2.eq
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.reset
import com.nhaarman.mockitokotlin2.times
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import io.sentry.IHub
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.SentryOptions
import io.sentry.SpanStatus
import io.sentry.TransactionContext
import kotlin.test.BeforeTest
import kotlin.test.Test
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.assertThrows
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.EnableAspectJAutoProxy
import org.springframework.context.annotation.Import
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig
import org.springframework.test.context.junit4.SpringRunner
@RunWith(SpringRunner::class)
@SpringJUnitConfig(SentryTransactionAdviceTest.Config::class)
class SentryTransactionAdviceTest {
@Autowired
lateinit var sampleService: SampleService
@Autowired
lateinit var classAnnotatedSampleService: ClassAnnotatedSampleService
@Autowired
lateinit var classAnnotatedWithOperationSampleService: ClassAnnotatedWithOperationSampleService
@Autowired
lateinit var hub: IHub
@BeforeTest
fun setup() {
reset(hub)
whenever(hub.startTransaction(any<String>(), any(), eq(true))).thenAnswer { io.sentry.SentryTracer(TransactionContext(it.arguments[0] as String, it.arguments[1] as String), hub) }
}
@Test
fun `creates transaction around method annotated with @SentryTransaction`() {
sampleService.methodWithTransactionNameSet()
verify(hub).captureTransaction(check {
assertThat(it.transaction).isEqualTo("customName")
assertThat(it.contexts.trace!!.operation).isEqualTo("bean")
assertThat(it.status).isEqualTo(SpanStatus.OK)
})
}
@Test
fun `when method annotated with @SentryTransaction throws exception, sets error status on transaction`() {
assertThrows<RuntimeException> { sampleService.methodThrowingException() }
verify(hub).captureTransaction(check {
assertThat(it.status).isEqualTo(SpanStatus.INTERNAL_ERROR)
})
}
@Test
fun `when @SentryTransaction has no name set, sets transaction name as className dot methodName`() {
sampleService.methodWithoutTransactionNameSet()
verify(hub).captureTransaction(check {
assertThat(it.transaction).isEqualTo("SampleService.methodWithoutTransactionNameSet")
assertThat(it.contexts.trace!!.operation).isEqualTo("op")
})
}
@Test
fun `when transaction is already active, does not start new transaction`() {
val scope = Scope(SentryOptions())
scope.setTransaction(io.sentry.SentryTracer(TransactionContext("aTransaction", "op"), hub))
whenever(hub.configureScope(any())).thenAnswer {
(it.arguments[0] as ScopeCallback).run(scope)
}
sampleService.methodWithTransactionNameSet()
verify(hub, times(0)).captureTransaction(any(), any())
}
@Test
fun `creates transaction around method in class annotated with @SentryTransaction`() {
classAnnotatedSampleService.hello()
verify(hub).captureTransaction(check {
assertThat(it.transaction).isEqualTo("ClassAnnotatedSampleService.hello")
assertThat(it.contexts.trace!!.operation).isEqualTo("op")
})
}
@Test
fun `creates transaction with operation set around method in class annotated with @SentryTransaction`() {
classAnnotatedWithOperationSampleService.hello()
verify(hub).captureTransaction(check {
assertThat(it.transaction).isEqualTo("ClassAnnotatedWithOperationSampleService.hello")
assertThat(it.contexts.trace!!.operation).isEqualTo("my-op")
})
}
@Test
fun `pushes the scope when advice starts`() {
classAnnotatedSampleService.hello()
verify(hub).pushScope()
}
@Test
fun `pops the scope when advice finishes`() {
classAnnotatedSampleService.hello()
verify(hub).popScope()
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Import(SentryTracingConfiguration::class)
open class Config {
@Bean
open fun sampleService() = SampleService()
@Bean
open fun classAnnotatedSampleService() = ClassAnnotatedSampleService()
@Bean
open fun classAnnotatedWithOperationSampleService() = ClassAnnotatedWithOperationSampleService()
@Bean
open fun hub() = mock<IHub>()
}
open class SampleService {
@SentryTransaction(name = "customName", operation = "bean")
open fun methodWithTransactionNameSet() = Unit
@SentryTransaction(operation = "op")
open fun methodWithoutTransactionNameSet() = Unit
@SentryTransaction(operation = "op")
open fun methodThrowingException(): Nothing = throw RuntimeException()
}
@SentryTransaction(operation = "op")
open class ClassAnnotatedSampleService {
open fun hello() = Unit
}
@SentryTransaction(operation = "my-op")
open class ClassAnnotatedWithOperationSampleService {
open fun hello() = Unit
}
}