• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package kotlinx.coroutines.debug
2 
3 import kotlinx.coroutines.*
4 import kotlinx.coroutines.channels.*
5 import org.junit.*
6 import reactor.blockhound.*
7 
8 @Suppress("UnusedEquals", "DeferredResultUnused", "BlockingMethodInNonBlockingContext")
9 class BlockHoundTest : TestBase() {
10 
11     @Before
initnull12     fun init() {
13         BlockHound.install()
14     }
15 
16     @Test(expected = BlockingOperationError::class)
<lambda>null17     fun testShouldDetectBlockingInDefault() = runTest {
18         withContext(Dispatchers.Default) {
19             Thread.sleep(1)
20         }
21     }
22 
23     @Test
<lambda>null24     fun testShouldNotDetectBlockingInIO() = runTest {
25         withContext(Dispatchers.IO) {
26             Thread.sleep(1)
27         }
28     }
29 
30     @Test
<lambda>null31     fun testShouldNotDetectNonblocking() = runTest {
32         withContext(Dispatchers.Default) {
33             val a = 1
34             val b = 2
35             assert(a + b == 3)
36         }
37     }
38 
39     @Test
<lambda>null40     fun testReusingThreads() = runTest {
41         val n = 100
42         repeat(n) {
43             async(Dispatchers.IO) {
44                 Thread.sleep(1)
45             }
46         }
47         repeat(n) {
48             async(Dispatchers.Default) {
49             }
50         }
51         repeat(n) {
52             async(Dispatchers.IO) {
53                 Thread.sleep(1)
54             }
55         }
56     }
57 
58     @Test
<lambda>null59     fun testBroadcastChannelNotBeingConsideredBlocking() = runTest {
60         withContext(Dispatchers.Default) {
61             // Copy of kotlinx.coroutines.channels.BufferedChannelTest.testSimple
62             val q = BroadcastChannel<Int>(1)
63             val s = q.openSubscription()
64             check(!q.isClosedForSend)
65             check(s.isEmpty)
66             check(!s.isClosedForReceive)
67             val sender = launch {
68                 q.send(1)
69                 q.send(2)
70             }
71             val receiver = launch {
72                 s.receive() == 1
73                 s.receive() == 2
74                 s.cancel()
75             }
76             sender.join()
77             receiver.join()
78         }
79     }
80 
81     @Test
<lambda>null82     fun testConflatedChannelNotBeingConsideredBlocking() = runTest {
83         withContext(Dispatchers.Default) {
84             val q = Channel<Int>(Channel.CONFLATED)
85             check(q.isEmpty)
86             check(!q.isClosedForReceive)
87             check(!q.isClosedForSend)
88             val sender = launch {
89                 q.send(1)
90             }
91             val receiver = launch {
92                 q.receive() == 1
93             }
94             sender.join()
95             receiver.join()
96         }
97     }
98 
99     @Test(expected = BlockingOperationError::class)
<lambda>null100     fun testReusingThreadsFailure() = runTest {
101         val n = 100
102         repeat(n) {
103             async(Dispatchers.IO) {
104                 Thread.sleep(1)
105             }
106         }
107         async(Dispatchers.Default) {
108             Thread.sleep(1)
109         }
110         repeat(n) {
111             async(Dispatchers.IO) {
112                 Thread.sleep(1)
113             }
114         }
115     }
116 }
117