diff --git a/src/test/java/sirius/kernel/async/TasksSpec.groovy b/src/test/java/sirius/kernel/async/TasksSpec.groovy deleted file mode 100644 index cd09d8d0..00000000 --- a/src/test/java/sirius/kernel/async/TasksSpec.groovy +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Made with all the love in the world - * by scireum in Remshalden, Germany - * - * Copyright by scireum GmbH - * http://www.scireum.de - info@scireum.de - */ - -package sirius.kernel.async - -import sirius.kernel.BaseSpecification -import sirius.kernel.commons.ValueHolder -import sirius.kernel.di.std.Part - -import java.time.Duration - -class TasksSpec extends BaseSpecification { - - @Part - public static Tasks tasks - - static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10) - - def "An executor executes work in the calling thread when full"() { - given: "a future the synchronize the threads" - Future thread2Finished = new Future() - and: "a place to store the thread id of the thread which executes the 2nd task" - ValueHolder executorThread = ValueHolder.of(null) - when: "we start one tasks which blocks the executor" - Future task1Future = tasks.executor("test-limited").start({ thread2Finished.await(DEFAULT_TIMEOUT) }) - and: "we start another task for the blocked executor" - Future task2Future = tasks.executor("test-limited").start({ - executorThread.set(Thread.currentThread().getId()) - thread2Finished.success() - }) - and: "we wait until all background tasks are done" - task1Future.await(DEFAULT_TIMEOUT) - task2Future.await(DEFAULT_TIMEOUT) - then: "we expect the second task to be executed in the calling thread" - Thread.currentThread().getId() == executorThread.get() - } - - def "An executor drops tasks (if possible) when full"() { - given: "a future the synchronize the threads" - Future thread2Finished = new Future() - and: "a place to store the fact that the task was dropped" - ValueHolder dropped = ValueHolder.of(null) - when: "we start one tasks which blocks the executor" - Future task1Future = tasks.executor("test-limited").start({ - thread2Finished.await(DEFAULT_TIMEOUT) - }) - and: "we start another task for the blocked executor" - Future task2Future = tasks.executor("test-limited").dropOnOverload({ - dropped.set(true) - thread2Finished.success() - }).start({ - dropped.set(false) - thread2Finished.success() - }) - and: "we wait until all background tasks are done" - task1Future.await(DEFAULT_TIMEOUT) - task2Future.await(DEFAULT_TIMEOUT) - then: "we expect the task the be dropped" - dropped.get() == true - and: "we expect the task1 to have successfully completed" - task1Future.isSuccessful() - and: "we expect the task1 to have failed" - task2Future.isFailed() - } - - def "An executor uses its work queue when full"() { - given: "futures the synchronize the threads" - Future thread2Started = new Future() - Future thread2Finished = new Future() - and: "a place to store the thread ids which executed the task" - ValueHolder task1Thread = ValueHolder.of(null) - ValueHolder task2Thread = ValueHolder.of(null) - when: "we start one tasks which blocks the executor" - tasks.executor("test-unlimited").start({ - task1Thread.set(Thread.currentThread().getId()) - thread2Started.await(DEFAULT_TIMEOUT) - }) - and: "we start another task for the blocked executor" - tasks.executor("test-unlimited").start({ - task2Thread.set(Thread.currentThread().getId()) - thread2Finished.success() - }) - thread2Started.success() - and: "we wait until all background tasks are done" - thread2Finished.await(DEFAULT_TIMEOUT) - then: "we expect both tasks to be executed in the same thread" - task1Thread.get() == task2Thread.get() - then: "we expect both tasks not to be executed in the main thread" - Thread.currentThread().getId() != task1Thread.get() - } - - def "An executor uses parallel threads if possible and required"() { - given: "a future the synchronize the threads" - Future thread2Finished = new Future() - and: "a place to store the thread ids which executed the task" - ValueHolder task1Thread = ValueHolder.of(null) - ValueHolder task2Thread = ValueHolder.of(null) - when: "we start one tasks which blocks the executor" - tasks.executor("test-parallel").start({ - task1Thread.set(Thread.currentThread().getId()) - thread2Finished.await(DEFAULT_TIMEOUT) - }) - and: "we start another task for the blocked executor" - tasks.executor("test-parallel").start({ - task2Thread.set(Thread.currentThread().getId()) - thread2Finished.success() - }) - and: "we wait until all background tasks are done" - thread2Finished.await(DEFAULT_TIMEOUT) - then: "we expect both tasks to be executed in different threads" - task1Thread.get() != task2Thread.get() - then: "we expect both tasks not to be executed in the main thread" - Thread.currentThread().getId() != task1Thread.get() - } - -} diff --git a/src/test/java/sirius/kernel/di/transformers/AutotransformerSpec.groovy b/src/test/java/sirius/kernel/di/transformers/AutotransformerSpec.groovy deleted file mode 100644 index eca6771d..00000000 --- a/src/test/java/sirius/kernel/di/transformers/AutotransformerSpec.groovy +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Made with all the love in the world - * by scireum in Remshalden, Germany - * - * Copyright by scireum GmbH - * http://www.scireum.de - info@scireum.de - */ - -package sirius.kernel.di.transformers - -import sirius.kernel.BaseSpecification - -class AutotransformerSpec extends BaseSpecification { - - def "Autotransforming into a subclass of TargetClassAutotransform works directly"() { - given: - def parent = new ParentClass() - expect: - parent.tryAs(TargetClassAutotransformChild.class).isPresent() - parent.as(TargetClassAutotransformChild.class) instanceof TargetClassAutotransformChild - } - - def "Autotransforming into a subclass of TargetClassAutotransform must not instantiate twice"() { - given: - def parent = new ParentClass() - expect: - parent.tryAs(TargetClassAutotransformChild.class).isPresent() - parent.as(TargetClassAutotransformChild.class) instanceof TargetClassAutotransformChild - parent.tryAs(TargetClassAutotransform.class).isPresent() - parent.as(TargetClassAutotransform.class) instanceof TargetClassAutotransform - } - - def "Autotransforming mixture of targets and target"() { - given: - def parent = new ParentClass() - expect: - parent.tryAs(TargetClassAutotransformChildWeird.class).isPresent() - parent.as(TargetClassAutotransformChildWeird.class) instanceof TargetClassAutotransformChildWeird - parent.tryAs(TargetClassAutotransform.class).isPresent() - parent.as(TargetClassAutotransform.class) instanceof TargetClassAutotransform - } - -} diff --git a/src/test/java/sirius/kernel/di/transformers/TransformersSpec.groovy b/src/test/java/sirius/kernel/di/transformers/TransformersSpec.groovy deleted file mode 100644 index cbbd9389..00000000 --- a/src/test/java/sirius/kernel/di/transformers/TransformersSpec.groovy +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Made with all the love in the world - * by scireum in Remshalden, Germany - * - * Copyright by scireum GmbH - * http://www.scireum.de - info@scireum.de - */ - -package sirius.kernel.di.transformers - -import sirius.kernel.BaseSpecification - -class TransformersSpec extends BaseSpecification { - - def "Transforming two classes regularly"() { - given: - def parent = new ParentClass() - expect: - parent.tryAs(TargetClass.class).isPresent() - parent.as(TargetClass.class) instanceof TargetClass - } - - def "Transforming first child class"() { - given: - def firstChild = new FirstChildClass() - expect: - firstChild.tryAs(TargetClass.class).isPresent() - firstChild.as(TargetClass.class) instanceof TargetClass - } - - def "Transforming second child class"() { - given: - def secondChild = new SecondChildClass() - expect: - secondChild.tryAs(TargetClass.class).isPresent() - secondChild.as(TargetClass.class) instanceof TargetClass - } -} diff --git a/src/test/kotlin/sirius/kernel/async/BackgroundLoopTest.kt b/src/test/kotlin/sirius/kernel/async/BackgroundLoopTest.kt index 6fd75259..2b1d2f0f 100644 --- a/src/test/kotlin/sirius/kernel/async/BackgroundLoopTest.kt +++ b/src/test/kotlin/sirius/kernel/async/BackgroundLoopTest.kt @@ -17,7 +17,7 @@ import kotlin.test.assertTrue @NightlyTest @ExtendWith(SiriusExtension::class) -class BackgroundLoopSpec { +class BackgroundLoopTest { @Test fun `BackgroundLoop limits to max frequency`() { val currentCounter = FastTestLoop.counter.toInt() diff --git a/src/test/kotlin/sirius/kernel/async/TasksTest.kt b/src/test/kotlin/sirius/kernel/async/TasksTest.kt new file mode 100644 index 00000000..a116a41f --- /dev/null +++ b/src/test/kotlin/sirius/kernel/async/TasksTest.kt @@ -0,0 +1,137 @@ +/* + * Made with all the love in the world + * by scireum in Remshalden, Germany + * + * Copyright by scireum GmbH + * http://www.scireum.de - info@scireum.de + */ + +package sirius.kernel.async + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import sirius.kernel.SiriusExtension +import sirius.kernel.commons.ValueHolder +import sirius.kernel.di.std.Part +import java.time.Duration +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals +import kotlin.test.assertTrue + +/** + * Tests the [Tasks] class. + */ +@ExtendWith(SiriusExtension::class) +class TasksTest { + + @Test + fun `An executor executes work in the calling thread when full`() { + // a future to synchronize the threads + val thread2Finished: Future = Future() + // a place to store the thread id of the thread which executes the 2nd task + val executorThread: ValueHolder = ValueHolder.of(null) + // we start one tasks which blocks the executor + val task1Future: Future = tasks.executor("test-limited").start { + thread2Finished.await(DEFAULT_TIMEOUT) + } + // we start another task for the blocked executor + val task2Future: Future = tasks.executor("test-limited").start { + executorThread.set(Thread.currentThread().id) + thread2Finished.success() + } + // we wait until all background tasks are done + task1Future.await(DEFAULT_TIMEOUT) + task2Future.await(DEFAULT_TIMEOUT) + // we expect the second task to be executed in the calling thread + assertEquals(Thread.currentThread().id, executorThread.get()) + } + + @Test + fun `An executor drops tasks (if possible) when full`() { + // a future to synchronize the threads + val thread2Finished: Future = Future() + // a place to store the fact that the task was dropped + val dropped: ValueHolder = ValueHolder.of(null) + // we start one tasks which blocks the executor + val task1Future: Future = tasks.executor("test-limited").start { + thread2Finished.await(DEFAULT_TIMEOUT) + } + // we start another task for the blocked executor + val task2Future: Future = tasks.executor("test-limited").dropOnOverload { + dropped.set(true) + thread2Finished.success() + }.start { + dropped.set(false) + thread2Finished.success() + } + // we wait until all background tasks are done + task1Future.await(DEFAULT_TIMEOUT) + task2Future.await(DEFAULT_TIMEOUT) + // we expect the task to be dropped + assertTrue { dropped.get() } + // we expect the task1 to have successfully completed + assertTrue { task1Future.isSuccessful } + // we expect the task1 to have failed + assertTrue { task2Future.isFailed } + } + + @Test + fun `An executor uses its work queue when full`() { + // futures to synchronize the threads + val thread2Started: Future = Future() + val thread2Finished: Future = Future() + // a place to store the thread ids which executed the task + val task1Thread: ValueHolder = ValueHolder.of(null) + val task2Thread: ValueHolder = ValueHolder.of(null) + // we start one tasks which blocks the executor + tasks.executor("test-unlimited").start { + task1Thread.set(Thread.currentThread().id) + thread2Started.await(DEFAULT_TIMEOUT) + } + // we start another task for the blocked executor + tasks.executor("test-unlimited").start { + task2Thread.set(Thread.currentThread().id) + thread2Finished.success() + } + thread2Started.success() + // we wait until all background tasks are done + thread2Finished.await(DEFAULT_TIMEOUT) + // we expect both tasks to be executed in the same thread + assertEquals(task1Thread.get(), task2Thread.get()) + // we expect both tasks not to be executed in the main thread + assertNotEquals(Thread.currentThread().id, task1Thread.get()) + } + + @Test + fun `An executor uses parallel threads if possible and required`() { + // a future to synchronize the threads + val thread2Finished: Future = Future() + // a place to store the thread ids which executed the task + val task1Thread: ValueHolder = ValueHolder.of(null) + val task2Thread: ValueHolder = ValueHolder.of(null) + // we start one tasks which blocks the executor + tasks.executor("test-parallel").start { + task1Thread.set(Thread.currentThread().id) + thread2Finished.await(DEFAULT_TIMEOUT) + } + // we start another task for the blocked executor + tasks.executor("test-parallel").start { + task2Thread.set(Thread.currentThread().id) + thread2Finished.success() + } + // we wait until all background tasks are done + thread2Finished.await(DEFAULT_TIMEOUT) + // we expect both tasks to be executed in different threads + assertNotEquals(task1Thread.get(), task2Thread.get()) + // we expect both tasks not to be executed in the main thread + assertNotEquals(Thread.currentThread().id, task1Thread.get()) + } + + companion object { + val DEFAULT_TIMEOUT: Duration = Duration.ofSeconds(10) + + @Part + @JvmStatic + private lateinit var tasks: Tasks + } +} diff --git a/src/test/kotlin/sirius/kernel/di/transformers/AutotransformerTest.kt b/src/test/kotlin/sirius/kernel/di/transformers/AutotransformerTest.kt new file mode 100644 index 00000000..9b28fcf4 --- /dev/null +++ b/src/test/kotlin/sirius/kernel/di/transformers/AutotransformerTest.kt @@ -0,0 +1,73 @@ +/* + * Made with all the love in the world + * by scireum in Remshalden, Germany + * + * Copyright by scireum GmbH + * http://www.scireum.de - info@scireum.de + */ + +package sirius.kernel.di.transformers + +import org.junit.jupiter.api.Assertions.assertInstanceOf +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import sirius.kernel.SiriusExtension +import kotlin.test.assertTrue + +/** + * Tests the [AutoTransform] mechanism. + */ +@ExtendWith(SiriusExtension::class) +class AutotransformerTest { + + @Test + fun `Autotransforming into a subclass of TargetClassAutotransform works directly`() { + val parent = ParentClass() + assertTrue { + parent.tryAs(TargetClassAutotransformChild::class.java).isPresent + } + assertInstanceOf( + TargetClassAutotransformChild::class.java, + parent.`as`(TargetClassAutotransformChild::class.java) + ) + } + + @Test + fun `Autotransforming into a subclass of TargetClassAutotransform must not instantiate twice`() { + val parent = ParentClass() + assertTrue { + parent.tryAs(TargetClassAutotransformChild::class.java).isPresent + } + assertInstanceOf( + TargetClassAutotransformChild::class.java, + parent.`as`(TargetClassAutotransformChild::class.java) + ) + assertTrue { + parent.tryAs(TargetClassAutotransform::class.java).isPresent + } + assertInstanceOf( + TargetClassAutotransform::class.java, + parent.`as`(TargetClassAutotransform::class.java) + ) + } + + @Test + fun `Autotransforming mixture of targets and target`() { + val parent = ParentClass() + assertTrue { + parent.tryAs(TargetClassAutotransformChildWeird::class.java).isPresent + } + assertInstanceOf( + TargetClassAutotransformChildWeird::class.java, + parent.`as`(TargetClassAutotransformChildWeird::class.java) + ) + assertTrue { + parent.tryAs(TargetClassAutotransform::class.java).isPresent + } + assertInstanceOf( + TargetClassAutotransform::class.java, + parent.`as`(TargetClassAutotransform::class.java) + ) + } + +} diff --git a/src/test/kotlin/sirius/kernel/di/transformers/TransformerTest.kt b/src/test/kotlin/sirius/kernel/di/transformers/TransformerTest.kt new file mode 100644 index 00000000..d8e13a37 --- /dev/null +++ b/src/test/kotlin/sirius/kernel/di/transformers/TransformerTest.kt @@ -0,0 +1,58 @@ +/* + * Made with all the love in the world + * by scireum in Remshalden, Germany + * + * Copyright by scireum GmbH + * http://www.scireum.de - info@scireum.de + */ + +package sirius.kernel.di.transformers + +import org.junit.jupiter.api.Assertions.assertInstanceOf +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import sirius.kernel.SiriusExtension +import kotlin.test.assertTrue + +/** + * Tests the [Transformer] class. + */ +@ExtendWith(SiriusExtension::class) +class TransformerTest { + + @Test + fun `Transforming two classes regularly`() { + val parent = ParentClass() + assertTrue { + parent.tryAs(TargetClass::class.java).isPresent + } + assertInstanceOf( + TargetClass::class.java, + parent.`as`(TargetClass::class.java) + ) + } + + @Test + fun `Transforming first child class`() { + val firstChild = FirstChildClass() + assertTrue { + firstChild.tryAs(TargetClass::class.java).isPresent + } + assertInstanceOf( + TargetClass::class.java, + firstChild.`as`(TargetClass::class.java) + ) + } + + @Test + fun `Transforming second child class`() { + val secondChild = SecondChildClass() + assertTrue { + secondChild.tryAs(TargetClass::class.java).isPresent + } + assertInstanceOf( + TargetClass::class.java, + secondChild.`as`(TargetClass::class.java) + ) + } +}