I'm added ktor to the Gradle project and the main code works find but I have problems with the tests. They are hanging
The server code:
package comfortable.data.server
import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.response.respondText
import io.ktor.routing.get
import io.ktor.routing.routing
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
fun Application.main() {
val server = embeddedServer(Netty, port = 8080) {
routing {
get("/books") {
val json = this::class.java.getResource("/books.json").readText()
call.respondText(json, ContentType.Application.Json)
}
}
}
server.start(wait = true)
}
and the test code:
package comfortable.data.server
import io.ktor.application.Application
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.assertEquals
import io.ktor.server.testing.withTestApplication
import io.ktor.server.testing.handleRequest
import io.ktor.http.HttpMethod
import io.ktor.http.HttpStatusCode
/**
* Testing class Server.
*/
class ServerTest {
@Test
fun testBookRequest() = withTestApplication(Application::main) {
with(handleRequest(HttpMethod.Get, "/books")) {
assertEquals(HttpStatusCode.OK, response.status())
assertEquals(true, response?.content?.contains("Solaris"))
}
}
}
Running with gradle test -i:
(after a while I use Ctrl-C to stop it)
> Task :test
comfortable.data.server.ServerTest > testBookRequest() STANDARD_OUT
10:42:42.468 [Test worker] INFO ktor.test - No ktor.deployment.watch patterns specified, automatic reload is not active
10:42:42.602 [Test worker] DEBUG io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework
10:42:42.613 [Test worker] DEBUG io.netty.channel.MultithreadEventLoopGroup - -Dio.netty.eventLoopThreads: 8
10:42:42.686 [Test worker] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.noKeySetOptimization: false
10:42:42.687 [Test worker] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.selectorAutoRebuildThreshold: 512
10:42:42.754 [Test worker] DEBUG io.netty.util.internal.PlatformDependent0 - -Dio.netty.noUnsafe: false
10:42:42.755 [Test worker] DEBUG io.netty.util.internal.PlatformDependent0 - Java version: 8
10:42:42.760 [Test worker] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.theUnsafe: available
10:42:42.764 [Test worker] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.copyMemory: available
10:42:42.772 [Test worker] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.Buffer.address: available
10:42:42.783 [Test worker] DEBUG io.netty.util.internal.PlatformDependent0 - direct buffer constructor: available
10:42:42.786 [Test worker] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.Bits.unaligned: available, true
10:42:42.787 [Test worker] DEBUG io.netty.util.internal.PlatformDependent0 - jdk.internal.misc.Unsafe.allocateUninitializedArray(int): unavailable prior to Java9
10:42:42.787 [Test worker] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.DirectByteBuffer.<init>(long, int): available
10:42:42.787 [Test worker] DEBUG io.netty.util.internal.PlatformDependent - sun.misc.Unsafe: available
10:42:42.788 [Test worker] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.tmpdir: /tmp (java.io.tmpdir)
10:42:42.788 [Test worker] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.bitMode: 64 (sun.arch.data.model)
10:42:42.797 [Test worker] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.noPreferDirect: false
10:42:42.797 [Test worker] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.maxDirectMemory: 2276458496 bytes
10:42:42.797 [Test worker] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.uninitializedArrayAllocationThreshold: -1
10:42:42.800 [Test worker] DEBUG io.netty.util.internal.CleanerJava6 - java.nio.ByteBuffer.cleaner(): available
10:42:42.851 [Test worker] DEBUG io.netty.util.internal.PlatformDependent - org.jctools-core.MpscChunkedArrayQueue: available
10:42:42.919 [Test worker] INFO ktor.application - No ktor.deployment.watch patterns specified, automatic reload is not active
10:42:43.006 [Test worker] INFO ktor.application - Responding at http://0.0.0.0:8080
10:42:43.068 [Test worker] DEBUG io.netty.channel.DefaultChannelId - -Dio.netty.processId: 28808 (auto-detected)
10:42:43.093 [Test worker] DEBUG io.netty.util.NetUtil - -Djava.net.preferIPv4Stack: false
10:42:43.096 [Test worker] DEBUG io.netty.util.NetUtil - -Djava.net.preferIPv6Addresses: false
10:42:43.103 [Test worker] DEBUG io.netty.util.NetUtil - Loopback interface: lo (lo, 0:0:0:0:0:0:0:1%lo)
10:42:43.107 [Test worker] DEBUG io.netty.util.NetUtil - /proc/sys/net/core/somaxconn: 128
10:42:43.109 [Test worker] DEBUG io.netty.channel.DefaultChannelId - -Dio.netty.machineId: 08:00:27:ff:fe:6e:7c:21 (auto-detected)
10:42:43.127 [Test worker] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.initialSize: 1024
10:42:43.128 [Test worker] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.maxSize: 4096
10:42:43.201 [Test worker] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.level: simple
10:42:43.202 [Test worker] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.targetRecords: 4
10:42:43.301 [Test worker] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numHeapArenas: 8
10:42:43.303 [Test worker] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numDirectArenas: 8
10:42:43.305 [Test worker] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.pageSize: 8192
10:42:43.313 [Test worker] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxOrder: 11
10:42:43.318 [Test worker] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.chunkSize: 16777216
10:42:43.321 [Test worker] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.tinyCacheSize: 512
10:42:43.323 [Test worker] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.smallCacheSize: 256
10:42:43.324 [Test worker] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.normalCacheSize: 64
10:42:43.325 [Test worker] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedBufferCapacity: 32768
10:42:43.327 [Test worker] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimInterval: 8192
10:42:43.329 [Test worker] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.useCacheForAllThreads: true
10:42:43.377 [Test worker] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.allocator.type: pooled
10:42:43.381 [Test worker] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.threadLocalDirectBufferSize: 0
10:42:43.386 [Test worker] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.maxThreadLocalCharBufferSize: 16384
<============-> 92% EXECUTING [1m 21s]
> :test > 8 tests completed
> :test > Executing test comfortable.data.server.ServerTest
When I change the Application to this ... the tests work fine but then I fail on running the server in normal mode
fun Application.main() {
routing {
get("/books") {
val json = this::class.java.getResource("/books.json").readText()
call.respondText(json, ContentType.Application.Json)
}
}
}
My application.conf look like following
ktor {
deployment {
port = 8080
}
application {
main = [ io.ktor.server.netty.EngineMain ]
}
}
In the build.gradle
jar {
manifest {
attributes(
'Main-Class': 'io.ktor.server.netty.EngineMain',
...
Running the jar I get an empty HTML page only ...
The tests start that Application.main method when you call testApp in your test. server.start never response, so that never finishes.
I had the same issue, and the same workaround. In order to get it working you need a new main file, which looks something like this:
import io.ktor.server.engine.commandLineEnvironment
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
fun main(args: Array<String>) {
embeddedServer(Netty, commandLineEnvironment(args)).start()
}
This is, in my estimation, a documentation bug more than anything
Thanks @wildunne I ran into this as well.
because at the beginning everything is difficult and usually people who run into this issue are just starting their adventure with ktor and maybe kotlin too, i've put @wildunne and @Nachtfeuer 's code together
Main.kt:
fun main(args: Array<String>) {
embeddedServer(Netty, commandLineEnvironment(args)).start()
}
Application.kt:
fun Application.module() {
routing {
get("/test") {
call.respondText("Hello login!!!", ContentType.Text.Plain)
}
}
}
ApplicationTest:
class ApplicationTest {
@Test
fun testRequestsOK() = withTestApplication(Application::module) {
with(handleRequest(HttpMethod.Get, "/test")) {
assertEquals(HttpStatusCode.OK, response.status())
assertEquals("Hello login!!!", response.content)
}
}
}
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
Resloved. Closed
Most helpful comment
The tests start that Application.main method when you call testApp in your test. server.start never response, so that never finishes.
I had the same issue, and the same workaround. In order to get it working you need a new
mainfile, which looks something like this:This is, in my estimation, a documentation bug more than anything