blob: e3831972c0f8bed676212d47ebd7ac1168417959 [file] [log] [blame]
package kotlinx.coroutines.experimental.io
import kotlinx.coroutines.experimental.TestBase
import kotlinx.coroutines.experimental.channels.ClosedReceiveChannelException
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.runBlocking
import kotlinx.coroutines.experimental.yield
import org.junit.*
import java.io.IOException
import kotlin.test.assertEquals
import kotlin.test.fail
class ByteBufferChannelScenarioTest : TestBase() {
private val ch = ByteBufferChannel(true)
@After
fun finish() {
ch.close(InterruptedException())
}
@Test
fun testReadBeforeAvailable() {
expect(1)
runBlocking {
launch(coroutineContext) {
expect(3)
val bb = ByteBuffer.allocate(10)
val rc = ch.readAvailable(bb) // should suspend
expect(5)
assertEquals(4, rc)
expect(6)
}
expect(2)
yield()
expect(4)
ch.writeInt(0xff) // should resume
yield()
finish(7)
}
}
@Test
fun testReadBeforeAvailable2() {
expect(1)
runBlocking {
launch(coroutineContext) {
expect(3)
val bb = ByteBuffer.allocate(4)
ch.readFully(bb) // should suspend
expect(5)
bb.flip()
assertEquals(4, bb.remaining())
expect(6)
}
expect(2)
yield()
expect(4)
ch.writeInt(0xff) // should resume
yield()
finish(7)
}
}
@Test
fun testReadAfterAvailable() {
expect(1)
runBlocking {
ch.writeInt(0xff) // should resume
launch(coroutineContext) {
expect(3)
val bb = ByteBuffer.allocate(10)
val rc = ch.readAvailable(bb) // should NOT suspend
expect(4)
assertEquals(4, rc)
expect(5)
}
expect(2)
yield()
finish(6)
}
}
@Test
fun testReadAfterAvailable2() {
expect(1)
runBlocking {
ch.writeInt(0xff) // should resume
launch(coroutineContext) {
expect(3)
val bb = ByteBuffer.allocate(4)
ch.readFully(bb) // should NOT suspend
expect(4)
bb.flip()
assertEquals(4, bb.remaining())
expect(5)
}
expect(2)
yield()
finish(6)
}
}
@Test
fun testReadToEmpty() {
runBlocking {
expect(1)
val rc = ch.readAvailable(ByteBuffer.allocate(0))
expect(2)
assertEquals(0, rc)
finish(3)
}
}
@Test
fun testReadToEmptyFromFailedChannel() {
runBlocking {
expect(1)
ch.close(IOException())
try {
ch.readAvailable(ByteBuffer.allocate(0))
fail("Should throw exception")
} catch (expected: IOException) {
}
finish(2)
}
}
@Test
fun testReadToEmptyFromClosedChannel() {
runBlocking {
expect(1)
ch.close()
val rc = ch.readAvailable(ByteBuffer.allocate(0))
expect(2)
assertEquals(-1, rc)
finish(3)
}
}
@Test
fun testReadFullyToEmptyFromClosedChannel() {
runBlocking {
expect(1)
ch.close()
ch.readFully(ByteBuffer.allocate(0))
finish(2)
}
}
@Test
fun testReadFullyFromClosedChannel() {
runBlocking {
expect(1)
ch.close()
try {
ch.readFully(ByteBuffer.allocate(1))
fail("Should throw exception")
} catch (expected: ClosedReceiveChannelException) {
}
finish(2)
}
}
@Test
fun testReadFullyToEmptyFromFailedChannel() {
runBlocking {
expect(1)
ch.close(IOException())
try {
ch.readFully(ByteBuffer.allocate(0))
fail("Should throw exception")
} catch (expected: IOException) {
}
finish(2)
}
}
@Test
fun testWriteBlock() {
runBlocking {
launch(coroutineContext) {
expect(1)
ch.write {
it.putLong(0x1234567812345678L)
}
expect(2)
}
yield()
expect(3)
assertEquals(0x1234567812345678L, ch.readLong())
assertEquals(0, ch.availableForRead)
finish(4)
}
}
@Test
fun testWriteBlockSuspend() {
runBlocking {
launch(coroutineContext) {
expect(1)
ch.writeFully(ByteArray(4088))
expect(2)
ch.write(8) {
it.putLong(0x1234567812345678L)
}
expect(4)
}
yield()
expect(3)
ch.readFully(ByteArray(9))
yield()
expect(5)
ch.readFully(ByteArray(4088 - 9))
expect(6)
assertEquals(0x1234567812345678L, ch.readLong())
assertEquals(0, ch.availableForRead)
finish(7)
}
}
@Test
fun testReadBlock() = runBlocking {
ch.writeLong(0x1234567812345678L)
ch.read {
assertEquals(0x1234567812345678L, it.getLong())
}
finish(1)
}
@Test
fun testReadBlockSuspend() = runBlocking {
ch.writeByte(0x12)
launch(coroutineContext) {
expect(1)
ch.read(8) {
assertEquals(0x1234567812345678L, it.getLong())
}
expect(3)
}
yield()
expect(2)
ch.writeLong(0x3456781234567800L)
yield()
expect(4)
ch.readByte()
assertEquals(0, ch.availableForRead)
finish(5)
}
@Test
fun testReadBlockSuspend2() = runBlocking {
launch(coroutineContext) {
expect(1)
ch.read(8) {
assertEquals(0x1234567812345678L, it.getLong())
}
expect(3)
}
yield()
expect(2)
ch.writeLong(0x1234567812345678L)
yield()
expect(4)
assertEquals(0, ch.availableForRead)
finish(5)
}
@Test
fun testWriteByteSuspend() = runBlocking {
launch(coroutineContext) {
expect(1)
ch.writeByte(1)
ch.writeFully(ByteArray(ch.availableForWrite))
expect(2)
ch.writeByte(1)
expect(5)
ch.close()
}
yield()
expect(3)
yield()
expect(4)
yield()
ch.readByte()
yield()
ch.readRemaining()
finish(6)
}
@Test
fun testWriteShortSuspend() = runBlocking {
launch(coroutineContext) {
expect(1)
ch.writeByte(1)
ch.writeFully(ByteArray(ch.availableForWrite))
expect(2)
ch.writeShort(1)
expect(5)
ch.close()
}
yield()
expect(3)
yield()
expect(4)
yield()
ch.readShort()
yield()
ch.readRemaining()
finish(6)
}
@Test
fun testWriteIntSuspend() = runBlocking {
launch(coroutineContext) {
expect(1)
ch.writeByte(1)
ch.writeFully(ByteArray(ch.availableForWrite))
expect(2)
ch.writeInt(1)
expect(5)
ch.close()
}
yield()
expect(3)
yield()
expect(4)
yield()
ch.readInt()
yield()
ch.readRemaining()
finish(6)
}
@Test
fun testWriteLongSuspend() = runBlocking {
launch(coroutineContext) {
expect(1)
ch.writeByte(1)
ch.writeFully(ByteArray(ch.availableForWrite))
expect(2)
ch.writeLong(1)
expect(5)
ch.close()
}
yield()
expect(3)
yield()
expect(4)
yield()
ch.readLong()
yield()
ch.readRemaining()
finish(6)
}
}