Skip to content

Instantly share code, notes, and snippets.

@logi
Last active September 16, 2018 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save logi/acefdd8fb0e60979b755dd24b095754b to your computer and use it in GitHub Desktop.
Save logi/acefdd8fb0e60979b755dd24b095754b to your computer and use it in GitHub Desktop.
/**
* Junit5 Extension which sets up a light-server BeforeAll tests and tears it down AfterAll.
* Use with `@ExtendWith(LightTestServer::class)`
*
* The first time a server is started in a particular VM, a random port is assigned to it to avoid clashes between
* concurrent test runs or other active servers.
*
* There are also static utility methods to make requests to the configured server.
*/
class LightTestServer() : BeforeAllCallback, AfterAllCallback {
// EXTENSION LIFE-CYCLE METHODS
override fun beforeAll(context: ExtensionContext?) {
Server.config.httpsPort = httpsPort
Server.start()
}
override fun afterAll(context: ExtensionContext?) {
Server.stop()
}
companion object {
val log = KotlinLogging.logger {}
// SERVER STATE
val httpsPort = randomFreePort(40000, 60000)
val baseUrl = "https://localhost:$httpsPort"
// MAKE REQUESTS TO SERVER
/** Make a GET request to the server maintained by this extension. */
fun makeGetRequest(path: String): ClientResponse {
return makeRequest(path, Methods.GET, null)
}
/** Make a POST request to the server maintained by this extension. */
fun makePostRequest(path: String, body: String): ClientResponse {
return makeRequest(path, Methods.POST, body)
}
/** Make a PUT request to the server maintained by this extension. */
fun makePutRequest(path: String, body: String): ClientResponse {
return makeRequest(path, Methods.PUT, body)
}
/** Make a DELETE request to the server maintained by this extension. */
fun makeDeleteRequest(path: String): ClientResponse {
return makeRequest(path, Methods.DELETE, null)
}
/** Make a request to the server maintained by this extension. */
fun makeRequest(path: String, method: HttpString, body: String?): ClientResponse {
log.info { "${method} :: $baseUrl :: ${path}" }
val client = Http2Client.getInstance()
client.connect(
URI(baseUrl),
Http2Client.WORKER,
Http2Client.SSL,
Http2Client.POOL,
OptionMap.create(UndertowOptions.ENABLE_HTTP2, true)
).get().use { connection ->
val request = ClientRequest().setPath(path).setMethod(method)
val latch = CountDownLatch(1)
val reference = AtomicReference<ClientResponse>()
val callback: ClientCallback<ClientExchange>
if (body == null) {
callback = client.createClientCallback(reference, latch)
} else {
log.info { "body: ${body}" }
val firstChar = if (body.length > 0) body[0] else '\u0000'
if (firstChar == '[' || firstChar == '{') {
request.requestHeaders.put(Headers.CONTENT_TYPE, "application/json")
} else {
request.requestHeaders.put(Headers.CONTENT_TYPE, "text/plain")
}
request.requestHeaders.put(Headers.TRANSFER_ENCODING, "chunked")
callback = client.createClientCallback(reference, latch, body)
}
connection.sendRequest(request, callback)
latch.await()
val response = reference.get()
log.info { "Response code = ${response.responseCode}" }
log.info { "Response body = ${response.getAttachment(Http2Client.RESPONSE_BODY)}" }
return response
}
}
}
}
@logi
Copy link
Author

logi commented Sep 16, 2018

Used like this (using kotlin and assertk):

@ExtendWith(LightTestServer::class)
class StatusTest {

    companion object {
        val log = KotlinLogging.logger {}
    }

    @Test
    fun testCallStatus() {
        val response = LightTestServer.makeGetRequest("/health")
        assert(response.responseCode, "RC").isEqualTo(200)
        assert(response.getAttachment(Http2Client.RESPONSE_BODY), "Body").isEqualTo("OK")
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment