blob: 2f837e5b4ad629d680a3711bf0db6d89c1f19b9e [file] [log] [blame]
Roman Elizarov7b2d8b02017-02-02 20:09:14 +03001package kotlinx.coroutines.experimental.channels
2
3import kotlinx.coroutines.experimental.*
4import org.junit.Test
5import kotlin.test.assertEquals
6import kotlin.test.assertFalse
7import kotlin.test.assertTrue
8
9class ArrayChannelTest : TestBase() {
10 @Test
11 fun testSimple() = runBlocking {
12 val q = ArrayChannel<Int>(1)
13 check(q.isEmpty && !q.isFull)
14 expect(1)
15 val sender = launch(context) {
16 expect(4)
17 q.send(1) // success -- buffered
18 check(!q.isEmpty && q.isFull)
19 expect(5)
20 q.send(2) // suspends (buffer full)
21 expect(9)
22 }
23 expect(2)
24 val receiver = launch(context) {
25 expect(6)
26 check(q.receive() == 1) // does not suspend -- took from buffer
27 check(!q.isEmpty && q.isFull) // waiting sender's element moved to buffer
28 expect(7)
29 check(q.receive() == 2) // does not suspend (takes from sender)
30 expect(8)
31 }
32 expect(3)
33 sender.join()
34 receiver.join()
35 check(q.isEmpty && !q.isFull)
36 finish(10)
37 }
38
39 @Test
40 fun testStress() = runBlocking {
41 val n = 100_000
42 val q = ArrayChannel<Int>(1)
43 val sender = launch(context) {
44 for (i in 1..n) q.send(i)
45 expect(2)
46 }
47 val receiver = launch(context) {
48 for (i in 1..n) check(q.receive() == i)
49 expect(3)
50 }
51 expect(1)
52 sender.join()
53 receiver.join()
54 finish(4)
55 }
56
57 @Test
58 fun testClosedBufferedReceiveOrNull() = runBlocking {
59 val q = ArrayChannel<Int>(1)
60 check(q.isEmpty && !q.isFull && !q.isClosedForSend && !q.isClosedForReceive)
61 expect(1)
62 launch(context) {
63 expect(5)
64 check(!q.isEmpty && !q.isFull && q.isClosedForSend && !q.isClosedForReceive)
65 assertEquals(42, q.receiveOrNull())
66 expect(6)
67 check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive)
68 assertEquals(null, q.receiveOrNull())
69 expect(7)
70 }
71 expect(2)
72 q.send(42) // buffers
73 expect(3)
74 q.close() // goes on
75 expect(4)
76 check(!q.isEmpty && !q.isFull && q.isClosedForSend && !q.isClosedForReceive)
77 yield()
78 check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive)
79 finish(8)
80 }
81
82 @Test
83 fun testClosedExceptions() = runBlocking {
84 val q = ArrayChannel<Int>(1)
85 expect(1)
86 launch(context) {
87 expect(4)
88 try { q.receive() }
89 catch (e: ClosedReceiveChannelException) {
90 expect(5)
91 }
92 }
93 expect(2)
94 q.close()
95 expect(3)
96 yield()
97 expect(6)
98 try { q.send(42) }
99 catch (e: ClosedSendChannelException) {
100 finish(7)
101 }
102 }
103
104 @Test
105 fun testOfferAndPool() = runBlocking {
106 val q = ArrayChannel<Int>(1)
107 assertTrue(q.offer(1))
108 expect(1)
109 launch(context) {
110 expect(3)
111 assertEquals(1, q.poll())
112 expect(4)
113 assertEquals(null, q.poll())
114 expect(5)
115 assertEquals(2, q.receive()) // suspends
116 expect(9)
117 assertEquals(3, q.poll())
118 expect(10)
119 assertEquals(null, q.poll())
120 expect(11)
121 }
122 expect(2)
123 yield()
124 expect(6)
125 assertTrue(q.offer(2))
126 expect(7)
127 assertTrue(q.offer(3))
128 expect(8)
129 assertFalse(q.offer(4))
130 yield()
131 finish(12)
132 }
133}