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