blob: 3f588785254040de25483881bbeb387201401e60 [file] [log] [blame]
dkhalanskyjb02b403d2020-04-06 16:33:22 +03001package kotlinx.coroutines.debug
2import kotlinx.coroutines.*
dkhalanskyjb45ba58e2020-10-26 11:40:38 +03003import kotlinx.coroutines.channels.*
dkhalanskyjb02b403d2020-04-06 16:33:22 +03004import org.junit.*
5import reactor.blockhound.*
6
Steve Elliottca095be2022-07-25 14:26:10 +00007@Suppress("UnusedEquals", "DeferredResultUnused", "BlockingMethodInNonBlockingContext")
dkhalanskyjb02b403d2020-04-06 16:33:22 +03008class BlockHoundTest : TestBase() {
9
10 @Before
11 fun init() {
12 BlockHound.install()
13 }
14
15 @Test(expected = BlockingOperationError::class)
Steve Elliottca095be2022-07-25 14:26:10 +000016 fun testShouldDetectBlockingInDefault() = runTest {
dkhalanskyjb02b403d2020-04-06 16:33:22 +030017 withContext(Dispatchers.Default) {
18 Thread.sleep(1)
19 }
20 }
21
22 @Test
Steve Elliottca095be2022-07-25 14:26:10 +000023 fun testShouldNotDetectBlockingInIO() = runTest {
dkhalanskyjb02b403d2020-04-06 16:33:22 +030024 withContext(Dispatchers.IO) {
25 Thread.sleep(1)
26 }
27 }
28
29 @Test
Steve Elliottca095be2022-07-25 14:26:10 +000030 fun testShouldNotDetectNonblocking() = runTest {
dkhalanskyjb02b403d2020-04-06 16:33:22 +030031 withContext(Dispatchers.Default) {
32 val a = 1
33 val b = 2
34 assert(a + b == 3)
35 }
36 }
37
38 @Test
39 fun testReusingThreads() = runTest {
40 val n = 100
41 repeat(n) {
42 async(Dispatchers.IO) {
43 Thread.sleep(1)
44 }
45 }
46 repeat(n) {
47 async(Dispatchers.Default) {
48 }
49 }
50 repeat(n) {
51 async(Dispatchers.IO) {
52 Thread.sleep(1)
53 }
54 }
55 }
56
dkhalanskyjb45ba58e2020-10-26 11:40:38 +030057 @Test
Steve Elliottca095be2022-07-25 14:26:10 +000058 fun testChannelNotBeingConsideredBlocking() = runTest {
dkhalanskyjb45ba58e2020-10-26 11:40:38 +030059 withContext(Dispatchers.Default) {
60 // Copy of kotlinx.coroutines.channels.ArrayChannelTest.testSimple
61 val q = Channel<Int>(1)
62 check(q.isEmpty)
63 check(!q.isClosedForReceive)
64 check(!q.isClosedForSend)
65 val sender = launch {
66 q.send(1)
67 q.send(2)
68 }
69 val receiver = launch {
70 q.receive() == 1
71 q.receive() == 2
72 }
73 sender.join()
74 receiver.join()
75 }
76 }
77
Steve Elliottca095be2022-07-25 14:26:10 +000078 @Test
79 fun testConflatedChannelsNotBeingConsideredBlocking() = runTest {
80 withContext(Dispatchers.Default) {
81 val q = Channel<Int>(Channel.CONFLATED)
82 check(q.isEmpty)
83 check(!q.isClosedForReceive)
84 check(!q.isClosedForSend)
85 val sender = launch {
86 q.send(1)
87 }
88 val receiver = launch {
89 q.receive() == 1
90 }
91 sender.join()
92 receiver.join()
93 }
94 }
95
dkhalanskyjb02b403d2020-04-06 16:33:22 +030096 @Test(expected = BlockingOperationError::class)
97 fun testReusingThreadsFailure() = runTest {
98 val n = 100
99 repeat(n) {
100 async(Dispatchers.IO) {
101 Thread.sleep(1)
102 }
103 }
104 async(Dispatchers.Default) {
105 Thread.sleep(1)
106 }
107 repeat(n) {
108 async(Dispatchers.IO) {
109 Thread.sleep(1)
110 }
111 }
112 }
113
114}