@@ -4,17 +4,16 @@ import android.os.SystemClock
4
4
import com.bugsnag.android.performance.internal.SpanFactory
5
5
import com.bugsnag.android.performance.test.CollectingSpanProcessor
6
6
import org.junit.Assert.assertEquals
7
+ import org.junit.Assert.assertNotNull
7
8
import org.junit.Assert.assertSame
8
- import org.junit.Assert.assertTrue
9
9
import org.junit.Before
10
10
import org.junit.Test
11
11
import org.junit.runner.RunWith
12
12
import org.robolectric.RobolectricTestRunner
13
13
import org.robolectric.annotation.Config
14
14
import org.robolectric.shadows.ShadowPausedSystemClock
15
- import java.lang.Thread.sleep
16
15
import java.util.concurrent.Callable
17
- import java.util.concurrent.CountDownLatch
16
+ import java.util.concurrent.SynchronousQueue
18
17
import java.util.concurrent.TimeUnit
19
18
20
19
@RunWith(RobolectricTestRunner ::class )
@@ -81,25 +80,28 @@ class ContextAwareScheduledThreadPoolExecutorTest {
81
80
fun scheduleWithFixedDelay () {
82
81
val scheduledExecutor = ContextAwareScheduledThreadPoolExecutor (1 )
83
82
var startTime = SystemClock .elapsedRealtime()
84
- val countDownLatch = CountDownLatch (2 )
83
+ // this is a weird use of SynchronousQueue - we use it to block until the appropriate spans are created
84
+ // we could probably use a Phaser or Semaphore instead but this is simpler to understand
85
+ // the span tasks put Units in the queue to signal that they have run, and we poll the queue to wait for them
86
+ val sync = SynchronousQueue <Unit >()
85
87
spanFactory.createCustomSpan(" parent" ).use {
86
88
scheduledExecutor.scheduleWithFixedDelay(
87
89
{
88
90
startTime + = 100L
89
91
SystemClock .setCurrentTimeMillis(startTime)
90
92
spanFactory.createCustomSpan(" child" ).end()
91
- countDownLatch.countDown( )
93
+ sync.put( Unit )
92
94
},
93
95
0L ,
94
96
100L ,
95
97
TimeUnit .MILLISECONDS ,
96
98
)
97
99
98
100
// end the parent span after one task execution
99
- sleep( 75L )
101
+ sync.poll( 500 , TimeUnit . MILLISECONDS )
100
102
}
101
103
102
- assertTrue(countDownLatch.await( 500L , TimeUnit .MILLISECONDS ))
104
+ assertNotNull(sync.poll( 500 , TimeUnit .MILLISECONDS ))
103
105
scheduledExecutor.shutdownNow()
104
106
105
107
val collectedSpans = spanProcessor.toList()
@@ -112,25 +114,28 @@ class ContextAwareScheduledThreadPoolExecutorTest {
112
114
fun scheduleAtFixedRate () {
113
115
val scheduledExecutor = ContextAwareScheduledThreadPoolExecutor (1 )
114
116
var startTime = SystemClock .elapsedRealtime()
115
- val countDownLatch = CountDownLatch (2 )
117
+ // this is a weird use of SynchronousQueue - we use it to block until the appropriate spans are created
118
+ // we could probably use a Phaser or Semaphore instead but this is simpler to understand
119
+ // the span tasks put Units in the queue to signal that they have run, and we poll the queue to wait for them
120
+ val sync = SynchronousQueue <Unit >()
116
121
spanFactory.createCustomSpan(" parent" ).use {
117
122
scheduledExecutor.scheduleAtFixedRate(
118
123
{
119
124
startTime + = 100L
120
125
SystemClock .setCurrentTimeMillis(startTime)
121
126
spanFactory.createCustomSpan(" child" ).end()
122
- countDownLatch.countDown( )
127
+ sync.put( Unit )
123
128
},
124
129
0L ,
125
130
100L ,
126
131
TimeUnit .MILLISECONDS ,
127
132
)
128
133
129
134
// end the parent span after one task execution
130
- sleep( 75L )
135
+ sync.poll( 500 , TimeUnit . MILLISECONDS )
131
136
}
132
137
133
- assertTrue(countDownLatch.await( 500L , TimeUnit .MILLISECONDS ))
138
+ assertNotNull(sync.poll( 500 , TimeUnit .MILLISECONDS ))
134
139
scheduledExecutor.shutdownNow()
135
140
136
141
val collectedSpans = spanProcessor.toList()
0 commit comments