@@ -4,13 +4,39 @@ import cats.effect.kernel.CancelScope.Cancelable
4
4
import cats .effect .{IO , Resource }
5
5
import cats .effect .unsafe .implicits .global
6
6
import cats .implicits .catsSyntaxTuple2Parallel
7
+ import org .scalatest .{Failed , Outcome , Retries , Canceled }
7
8
import org .scalatest .matchers .should .Matchers
9
+ import org .scalatest .tags .Retryable
8
10
import org .scalatest .wordspec .AnyWordSpec
9
- import java .util .concurrent .atomic .AtomicBoolean
10
11
12
+ import java .util .concurrent .atomic .AtomicBoolean
11
13
import scala .concurrent .duration .DurationInt
12
14
13
- class CancellationUnitTest extends AnyWordSpec with Matchers {
15
+ @ Retryable
16
+ class CancellationUnitTest extends AnyWordSpec with Matchers with Retries {
17
+
18
+ val retries = 5
19
+
20
+ override def withFixture (test : NoArgTest ): Outcome = {
21
+ if (isRetryable(test)) withFixture(test, retries)
22
+ else super .withFixture(test)
23
+ }
24
+
25
+ def withFixture (test : NoArgTest , count : Int ): Outcome = {
26
+ val outcome = super .withFixture(test)
27
+ outcome match {
28
+ case Failed (_) | Canceled (_) =>
29
+ if (count == 1 ) super .withFixture(test)
30
+ else {
31
+ println(
32
+ s " Retrying SchedulerUnitTest flaky test ` ${test.name}`, Attempts remaining: ${count - 1 }"
33
+ )
34
+ // scheduling the retry after 1 second
35
+ withRetry(1 .seconds)(withFixture(test, count - 1 ))
36
+ }
37
+ case other => other
38
+ }
39
+ }
14
40
15
41
" Cancellation" should {
16
42
" cancel the fiber directly and execute the action on cancellation" in {
@@ -87,7 +113,7 @@ class CancellationUnitTest extends AnyWordSpec with Matchers {
87
113
val flag = new AtomicBoolean (false )
88
114
val ioa = IO .blocking {
89
115
while (! flag.get()) {
90
- Thread .sleep(15 )
116
+ Thread .sleep(25 )
91
117
println(s " counter = $counter" )
92
118
counter += 1
93
119
}
0 commit comments