BAEL-867 coroutines tests (#2011)
* BAEL-867 coroutines tests * BAEL-867 add two channels examples * BAEL-867 fix example * BAEL-867 remove channels * BAEL-867 optimize imports * BAEL-867 remove kotlin module
This commit is contained in:
parent
df782e425b
commit
69c330eb6c
|
@ -13,6 +13,15 @@
|
|||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>central</id>
|
||||
<url>http://jcenter.bintray.com</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
|
@ -31,6 +40,11 @@
|
|||
<version>${kotlin-reflect.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlinx</groupId>
|
||||
<artifactId>kotlinx-coroutines-core</artifactId>
|
||||
<version>${kotlinx.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
@ -104,10 +118,11 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<kotlin-maven-plugin.version>1.1.1</kotlin-maven-plugin.version>
|
||||
<kotlin-test-junit.version>1.1.1</kotlin-test-junit.version>
|
||||
<kotlin-stdlib.version>1.1.1</kotlin-stdlib.version>
|
||||
<kotlin-reflect.version>1.1.1</kotlin-reflect.version>
|
||||
<kotlin-maven-plugin.version>1.1.2</kotlin-maven-plugin.version>
|
||||
<kotlin-test-junit.version>1.1.2</kotlin-test-junit.version>
|
||||
<kotlin-stdlib.version>1.1.2</kotlin-stdlib.version>
|
||||
<kotlin-reflect.version>1.1.2</kotlin-reflect.version>
|
||||
<kotlinx.version>0.15</kotlinx.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,179 @@
|
|||
package com.baeldung.kotlin
|
||||
|
||||
import kotlinx.coroutines.experimental.*
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.coroutines.experimental.buildSequence
|
||||
import kotlin.system.measureTimeMillis
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
||||
class CoroutinesTest {
|
||||
|
||||
@Test
|
||||
fun givenBuildSequence_whenTakeNElements_thenShouldReturnItInALazyWay() {
|
||||
//given
|
||||
val fibonacciSeq = buildSequence {
|
||||
var a = 0
|
||||
var b = 1
|
||||
|
||||
yield(1)
|
||||
|
||||
while (true) {
|
||||
yield(a + b)
|
||||
|
||||
val tmp = a + b
|
||||
a = b
|
||||
b = tmp
|
||||
}
|
||||
}
|
||||
|
||||
//when
|
||||
val res = fibonacciSeq.take(5).toList()
|
||||
|
||||
//then
|
||||
assertEquals(res, listOf(1, 1, 2, 3, 5))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenLazySeq_whenTakeNElements_thenShouldReturnAllElements() {
|
||||
//given
|
||||
val lazySeq = buildSequence {
|
||||
print("START ")
|
||||
for (i in 1..5) {
|
||||
yield(i)
|
||||
print("STEP ")
|
||||
}
|
||||
print("END")
|
||||
}
|
||||
//when
|
||||
val res = lazySeq.take(10).toList()
|
||||
|
||||
//then
|
||||
assertEquals(res, listOf(1, 2, 3, 4, 5))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenAsyncCoroutine_whenStartIt_thenShouldExecuteItInTheAsyncWay() {
|
||||
//given
|
||||
val res = mutableListOf<String>()
|
||||
|
||||
//when
|
||||
runBlocking<Unit> {
|
||||
val promise = launch(CommonPool) { expensiveComputation(res) }
|
||||
res.add("Hello,")
|
||||
promise.join()
|
||||
}
|
||||
|
||||
//then
|
||||
assertEquals(res, listOf("Hello,", "word!"))
|
||||
}
|
||||
|
||||
|
||||
suspend fun expensiveComputation(res: MutableList<String>) {
|
||||
delay(1000L)
|
||||
res.add("word!")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenHugeAmountOfCoroutines_whenStartIt_thenShouldExecuteItWithoutOutOfMemory() {
|
||||
runBlocking<Unit> {
|
||||
//given
|
||||
val counter = AtomicInteger(0)
|
||||
val numberOfCoroutines = 100_000
|
||||
|
||||
//when
|
||||
val jobs = List(numberOfCoroutines) {
|
||||
launch(CommonPool) {
|
||||
delay(1L)
|
||||
counter.incrementAndGet()
|
||||
}
|
||||
}
|
||||
jobs.forEach { it.join() }
|
||||
|
||||
//then
|
||||
assertEquals(counter.get(), numberOfCoroutines)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenCancellableJob_whenRequestForCancel_thenShouldQuit() {
|
||||
runBlocking<Unit> {
|
||||
//given
|
||||
val job = launch(CommonPool) {
|
||||
while (isActive) {
|
||||
println("is working")
|
||||
}
|
||||
}
|
||||
|
||||
delay(1300L)
|
||||
|
||||
//when
|
||||
job.cancel()
|
||||
|
||||
//then cancel successfully
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = CancellationException::class)
|
||||
fun givenAsyncAction_whenDeclareTimeout_thenShouldFinishWhenTimedOut() {
|
||||
runBlocking<Unit> {
|
||||
withTimeout(1300L) {
|
||||
repeat(1000) { i ->
|
||||
println("Some expensive computation $i ...")
|
||||
delay(500L)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenHaveTwoExpensiveAction_whenExecuteThemAsync_thenTheyShouldRunConcurrently() {
|
||||
runBlocking<Unit> {
|
||||
val delay = 1000L
|
||||
val time = measureTimeMillis {
|
||||
//given
|
||||
val one = async(CommonPool) { someExpensiveComputation(delay) }
|
||||
val two = async(CommonPool) { someExpensiveComputation(delay) }
|
||||
|
||||
//when
|
||||
runBlocking {
|
||||
one.await()
|
||||
two.await()
|
||||
}
|
||||
}
|
||||
|
||||
//then
|
||||
assertTrue(time < delay * 2)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenTwoExpensiveAction_whenExecuteThemLazy_thenTheyShouldNotConcurrently() {
|
||||
runBlocking<Unit> {
|
||||
val delay = 1000L
|
||||
val time = measureTimeMillis {
|
||||
//given
|
||||
val one = async(CommonPool, CoroutineStart.LAZY) { someExpensiveComputation(delay) }
|
||||
val two = async(CommonPool, CoroutineStart.LAZY) { someExpensiveComputation(delay) }
|
||||
|
||||
//when
|
||||
runBlocking {
|
||||
one.await()
|
||||
two.await()
|
||||
}
|
||||
}
|
||||
|
||||
//then
|
||||
assertTrue(time > delay * 2)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun someExpensiveComputation(delayInMilliseconds: Long) {
|
||||
delay(delayInMilliseconds)
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue