blob: c7afd0e29c3d66c4793c62fa80df86cb342eb51c [file] [log] [blame]
Sergey Mashkovb87d6362017-08-23 11:58:06 +03001package kotlinx.coroutines.experimental.io
2
Roman Elizarov9fe5f462018-02-21 19:05:52 +03003import kotlinx.coroutines.experimental.*
4import kotlinx.coroutines.experimental.channels.*
Sergey Mashkove6764082017-12-05 12:27:09 +03005import kotlinx.coroutines.experimental.io.internal.*
Sergey Mashkovc51ecd32017-10-27 22:42:39 +03006import org.junit.*
Sergey Mashkovdfae5e22017-12-18 19:31:27 +03007import org.junit.Test
Roman Elizarov9fe5f462018-02-21 19:05:52 +03008import java.io.*
9import kotlin.coroutines.experimental.*
Sergey Mashkovdfae5e22017-12-18 19:31:27 +030010import kotlin.test.*
Sergey Mashkovb87d6362017-08-23 11:58:06 +030011
12class ByteBufferChannelScenarioTest : TestBase() {
13 private val ch = ByteBufferChannel(true)
14
Sergey Mashkovc51ecd32017-10-27 22:42:39 +030015 @After
16 fun finish() {
17 ch.close(InterruptedException())
18 }
19
Sergey Mashkovb87d6362017-08-23 11:58:06 +030020 @Test
21 fun testReadBeforeAvailable() {
22 expect(1)
23
24 runBlocking {
25 launch(coroutineContext) {
26 expect(3)
27
28 val bb = ByteBuffer.allocate(10)
29 val rc = ch.readAvailable(bb) // should suspend
30
31 expect(5)
32 assertEquals(4, rc)
33
34 expect(6)
35 }
36
37 expect(2)
38 yield()
39
40 expect(4)
41 ch.writeInt(0xff) // should resume
42
43 yield()
44
45 finish(7)
46 }
47 }
48
49 @Test
50 fun testReadBeforeAvailable2() {
51 expect(1)
52
53 runBlocking {
54 launch(coroutineContext) {
55 expect(3)
56
57 val bb = ByteBuffer.allocate(4)
58 ch.readFully(bb) // should suspend
59
60 expect(5)
61
62 bb.flip()
63 assertEquals(4, bb.remaining())
64
65 expect(6)
66 }
67
68 expect(2)
69 yield()
70
71 expect(4)
72 ch.writeInt(0xff) // should resume
73
74 yield()
75
76 finish(7)
77 }
78 }
79
80 @Test
81 fun testReadAfterAvailable() {
82 expect(1)
83
84 runBlocking {
85 ch.writeInt(0xff) // should resume
86
87 launch(coroutineContext) {
88 expect(3)
89
90 val bb = ByteBuffer.allocate(10)
91 val rc = ch.readAvailable(bb) // should NOT suspend
92
93 expect(4)
94 assertEquals(4, rc)
95
96 expect(5)
97 }
98
99 expect(2)
100 yield()
101
102 finish(6)
103 }
104 }
105
106 @Test
107 fun testReadAfterAvailable2() {
108 expect(1)
109
110 runBlocking {
111 ch.writeInt(0xff) // should resume
112
113 launch(coroutineContext) {
114 expect(3)
115
116 val bb = ByteBuffer.allocate(4)
117 ch.readFully(bb) // should NOT suspend
118
119 expect(4)
120 bb.flip()
121 assertEquals(4, bb.remaining())
122
123 expect(5)
124 }
125
126 expect(2)
127 yield()
128
129 finish(6)
130 }
131 }
132
133 @Test
134 fun testReadToEmpty() {
135 runBlocking {
136 expect(1)
137
138 val rc = ch.readAvailable(ByteBuffer.allocate(0))
139
140 expect(2)
141
142 assertEquals(0, rc)
143
144 finish(3)
145 }
146 }
147
148 @Test
149 fun testReadToEmptyFromFailedChannel() {
150 runBlocking {
151 expect(1)
152
153 ch.close(IOException())
154
155 try {
156 ch.readAvailable(ByteBuffer.allocate(0))
157 fail("Should throw exception")
158 } catch (expected: IOException) {
159 }
160
161 finish(2)
162 }
163 }
164
165 @Test
166 fun testReadToEmptyFromClosedChannel() {
167 runBlocking {
168 expect(1)
169
170 ch.close()
171
172 val rc = ch.readAvailable(ByteBuffer.allocate(0))
173
174 expect(2)
175
176 assertEquals(-1, rc)
177
178 finish(3)
179 }
180 }
181
182 @Test
183 fun testReadFullyToEmptyFromClosedChannel() {
184 runBlocking {
185 expect(1)
186
187 ch.close()
188
189 ch.readFully(ByteBuffer.allocate(0))
190
191 finish(2)
192 }
193 }
194
195 @Test
196 fun testReadFullyFromClosedChannel() {
197 runBlocking {
198 expect(1)
199
200 ch.close()
201 try {
202 ch.readFully(ByteBuffer.allocate(1))
203 fail("Should throw exception")
204 } catch (expected: ClosedReceiveChannelException) {
205 }
206
207 finish(2)
208 }
209 }
210
211 @Test
212 fun testReadFullyToEmptyFromFailedChannel() {
213 runBlocking {
214 expect(1)
215
216 ch.close(IOException())
217
218 try {
219 ch.readFully(ByteBuffer.allocate(0))
220 fail("Should throw exception")
221 } catch (expected: IOException) {
222 }
223
224 finish(2)
225 }
226 }
Sergey Mashkov75101172017-09-25 19:41:08 +0300227
228 @Test
229 fun testWriteBlock() {
230 runBlocking {
231 launch(coroutineContext) {
232 expect(1)
233
234 ch.write {
235 it.putLong(0x1234567812345678L)
236 }
237
238 expect(2)
239 }
240
241 yield()
242 expect(3)
243
244 assertEquals(0x1234567812345678L, ch.readLong())
245 assertEquals(0, ch.availableForRead)
246
247 finish(4)
248 }
249 }
250
251 @Test
252 fun testWriteBlockSuspend() {
253 runBlocking {
254 launch(coroutineContext) {
255 expect(1)
256
257 ch.writeFully(ByteArray(4088))
258
259 expect(2)
260
261 ch.write(8) {
262 it.putLong(0x1234567812345678L)
263 }
264
265 expect(4)
266 }
267
268 yield()
269 expect(3)
270
271 ch.readFully(ByteArray(9))
272 yield()
273 expect(5)
274
275 ch.readFully(ByteArray(4088 - 9))
276
277 expect(6)
278
279 assertEquals(0x1234567812345678L, ch.readLong())
280 assertEquals(0, ch.availableForRead)
281
282 finish(7)
283 }
284 }
285
286 @Test
287 fun testReadBlock() = runBlocking {
288 ch.writeLong(0x1234567812345678L)
289
290 ch.read {
291 assertEquals(0x1234567812345678L, it.getLong())
292 }
293
294 finish(1)
295 }
296
297 @Test
298 fun testReadBlockSuspend() = runBlocking {
299 ch.writeByte(0x12)
300
301 launch(coroutineContext) {
302 expect(1)
303 ch.read(8) {
304 assertEquals(0x1234567812345678L, it.getLong())
305 }
306
307 expect(3)
308 }
309
310 yield()
311 expect(2)
312
313 ch.writeLong(0x3456781234567800L)
314 yield()
315
316 expect(4)
317 ch.readByte()
318 assertEquals(0, ch.availableForRead)
319
320 finish(5)
321 }
322
323 @Test
324 fun testReadBlockSuspend2() = runBlocking {
325 launch(coroutineContext) {
326 expect(1)
327 ch.read(8) {
328 assertEquals(0x1234567812345678L, it.getLong())
329 }
330
331 expect(3)
332 }
333
334 yield()
335 expect(2)
336
337 ch.writeLong(0x1234567812345678L)
338 yield()
339
340 expect(4)
341 assertEquals(0, ch.availableForRead)
342
343 finish(5)
344 }
Sergey Mashkovbab9f792017-11-07 19:42:15 +0300345
346 @Test
347 fun testWriteByteSuspend() = runBlocking {
348 launch(coroutineContext) {
349 expect(1)
350 ch.writeByte(1)
351 ch.writeFully(ByteArray(ch.availableForWrite))
352 expect(2)
353 ch.writeByte(1)
354 expect(5)
355 ch.close()
356 }
357
358 yield()
359 expect(3)
360 yield()
361 expect(4)
362 yield()
363
364 ch.readByte()
365 yield()
366
367 ch.readRemaining()
368 finish(6)
369 }
370
371 @Test
372 fun testWriteShortSuspend() = runBlocking {
373 launch(coroutineContext) {
374 expect(1)
375 ch.writeByte(1)
376 ch.writeFully(ByteArray(ch.availableForWrite))
377 expect(2)
378 ch.writeShort(1)
379 expect(5)
380 ch.close()
381 }
382
383 yield()
384 expect(3)
385 yield()
386 expect(4)
387 yield()
388
389 ch.readShort()
390 yield()
391
392 ch.readRemaining()
393 finish(6)
394 }
395
396 @Test
397 fun testWriteIntSuspend() = runBlocking {
398 launch(coroutineContext) {
399 expect(1)
400 ch.writeByte(1)
401 ch.writeFully(ByteArray(ch.availableForWrite))
402 expect(2)
403 ch.writeInt(1)
404 expect(5)
405 ch.close()
406 }
407
408 yield()
409 expect(3)
410 yield()
411 expect(4)
412 yield()
413
414 ch.readInt()
415 yield()
416
417 ch.readRemaining()
418 finish(6)
419 }
420
421 @Test
Sergey Mashkove6764082017-12-05 12:27:09 +0300422 fun testWriteIntThenRead() = runBlocking {
423 val size = BUFFER_SIZE - RESERVED_SIZE - 3
424
425 expect(1)
426 ch.writeFully(java.nio.ByteBuffer.allocate(size))
427 ch.flush()
428 expect(2)
429
430 launch(coroutineContext) {
431 expect(4)
432 ch.readPacket(size).release()
433 }
434
435 // coroutine is pending
436 expect(3)
437 ch.writeInt(0x11223344)
438 expect(5)
439
440 assertEquals(0x11223344, ch.readInt())
441
442 finish(6)
443 }
444
445 @Test
Sergey Mashkovbab9f792017-11-07 19:42:15 +0300446 fun testWriteLongSuspend() = runBlocking {
447 launch(coroutineContext) {
448 expect(1)
449 ch.writeByte(1)
450 ch.writeFully(ByteArray(ch.availableForWrite))
451 expect(2)
452 ch.writeLong(1)
453 expect(5)
454 ch.close()
455 }
456
457 yield()
458 expect(3)
459 yield()
460 expect(4)
461 yield()
462
463 ch.readLong()
464 yield()
465
466 ch.readRemaining()
467 finish(6)
468 }
469
Sergey Mashkov4df720f2017-12-05 16:45:55 +0300470 @Test
471 fun testDiscardExisting() = runBlocking {
472 launch(coroutineContext) {
473 expect(1)
474 ch.writeInt(1)
475 ch.writeInt(2)
476 expect(2)
477 }
478
479 yield()
480 expect(3)
481
482 assertEquals(4, ch.discard(4))
483 assertEquals(2, ch.readInt())
484
485 finish(4)
486 }
487
488 @Test
489 fun testDiscardPartiallyExisting() = runBlocking {
490 ch.writeInt(1)
491
492 launch(coroutineContext) {
493 expect(1)
494 assertEquals(8, ch.discard(8))
495 expect(3)
496 }
497
498 yield()
499 expect(2)
500
501 ch.writeInt(2)
502 yield()
503
504 expect(4)
505 assertEquals(0, ch.availableForRead)
506 finish(5)
507 }
508
509 @Test
510 fun testDiscardPartiallyExisting2() = runBlocking {
511 launch(coroutineContext) {
512 expect(1)
513 assertEquals(8, ch.discard(8))
514 expect(4)
515 }
516
517 yield()
518
519 expect(2)
520 ch.writeInt(1)
521 yield()
522 expect(3)
523 assertEquals(0, ch.availableForRead)
524
525 ch.writeInt(2)
526 yield()
527 expect(5)
528 assertEquals(0, ch.availableForRead)
529 finish(6)
530 }
531
532 @Test
533 fun testDiscardClose() = runBlocking {
534 launch(coroutineContext) {
535 expect(1)
536 assertEquals(8, ch.discard())
537 expect(4)
538 }
539
540 yield()
541
542 expect(2)
543 ch.writeInt(1)
544 yield()
545 ch.writeInt(2)
546 yield()
547
548 expect(3)
549 ch.close()
550 yield()
551
552 finish(5)
553 }
Sergey Mashkovdfae5e22017-12-18 19:31:27 +0300554
555 @Test
556 fun testWriteWhile() = runBlocking {
557 val size = 16384
558
559 launch(coroutineContext) {
560 expect(1)
561 var b: Byte = 0
562 var count = 0
563
564 ch.writeWhile { buffer ->
565 while (buffer.hasRemaining() && count < size) {
566 buffer.put(b++)
567 count++
568 }
569 count < size
570 }
571 expect(3)
572 ch.close()
573 }
574
575 yield()
576
577 expect(2)
578
579 val buffer = ByteArray(size)
580 ch.readFully(buffer)
581
582 var expectedB: Byte = 0
583 for (i in buffer.indices) {
584 assertEquals(expectedB, buffer[i])
585 expectedB++
586 }
587
588 yield()
589 yield()
590
591 finish(4)
592 assertTrue(ch.isClosedForRead)
593 }
Sergey Mashkovb87d6362017-08-23 11:58:06 +0300594}