@@ -3,7 +3,9 @@ package io.sentry
33import io.sentry.test.getCtor
44import io.sentry.test.getProperty
55import io.sentry.test.injectForField
6+ import io.sentry.util.thread.MainThreadChecker
67import org.mockito.kotlin.any
8+ import org.mockito.kotlin.atLeast
79import org.mockito.kotlin.eq
810import org.mockito.kotlin.mock
911import org.mockito.kotlin.never
@@ -27,6 +29,7 @@ class TransactionPerformanceCollectorTest {
2729 private val className = " io.sentry.DefaultTransactionPerformanceCollector"
2830 private val ctorTypes: Array <Class <* >> = arrayOf(SentryOptions ::class .java)
2931 private val fixture = Fixture ()
32+ private val mainThreadChecker = MainThreadChecker .getInstance()
3033
3134 private class Fixture {
3235 lateinit var transaction1: ITransaction
@@ -71,7 +74,7 @@ class TransactionPerformanceCollectorTest {
7174 transaction1 = SentryTracer (TransactionContext (" " , " " ), hub)
7275 transaction2 = SentryTracer (TransactionContext (" " , " " ), hub)
7376 val collector = DefaultTransactionPerformanceCollector (options)
74- val timer: Timer ? = collector.getProperty(" timer" ) ? : Timer (true )
77+ val timer: Timer = collector.getProperty(" timer" ) ? : Timer (true )
7578 mockTimer = spy(timer)
7679 collector.injectForField(" timer" , mockTimer)
7780 return collector
@@ -101,6 +104,7 @@ class TransactionPerformanceCollectorTest {
101104 val cpuCollector = mock<ICollector >()
102105 val collector = fixture.getSut(memoryCollector, cpuCollector)
103106 collector.start(fixture.transaction1)
107+ Thread .sleep(300 )
104108 verify(memoryCollector).setup()
105109 verify(cpuCollector).setup()
106110 }
@@ -197,4 +201,35 @@ class TransactionPerformanceCollectorTest {
197201 // We have the same number of memory and cpu data, even if we have 2 memory collectors and 1 cpu collector
198202 assertEquals(data1.memoryData.size, data1.cpuData.size)
199203 }
204+
205+ @Test
206+ fun `setup and collect happen on background thread` () {
207+ val threadCheckerCollector = spy(ThreadCheckerCollector ())
208+ fixture.options.addCollector(threadCheckerCollector)
209+ val collector = fixture.getSut()
210+ // We have the ThreadCheckerCollector in the collectors
211+ assertTrue(fixture.options.collectors.any { it is ThreadCheckerCollector })
212+
213+ collector.start(fixture.transaction1)
214+ // Let's sleep to make the collector get values
215+ Thread .sleep(300 )
216+ collector.stop(fixture.transaction1)
217+
218+ verify(threadCheckerCollector).setup()
219+ verify(threadCheckerCollector, atLeast(1 )).collect(any())
220+ }
221+
222+ inner class ThreadCheckerCollector : ICollector {
223+ override fun setup () {
224+ if (mainThreadChecker.isMainThread) {
225+ throw AssertionError (" setup() was called in the main thread" )
226+ }
227+ }
228+
229+ override fun collect (performanceCollectionData : MutableIterable <PerformanceCollectionData >) {
230+ if (mainThreadChecker.isMainThread) {
231+ throw AssertionError (" collect() was called in the main thread" )
232+ }
233+ }
234+ }
200235}
0 commit comments