Skip to content

Commit

Permalink
Setter ApplicationState initially til false, for å ikke få false posi… (
Browse files Browse the repository at this point in the history
#279)

* Setter ApplicationState initially til false, for å ikke få false positives under oppstart

* Setter ApplicationState til ready først ved ServerReady, ved ApplicationStarted er den ikke nødvendigvis klar for å ta imot connections enda.

* Tester for readyness- og livenesstester
  • Loading branch information
inavga authored Nov 27, 2024
1 parent 576d00a commit 832ed16
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 14 deletions.
4 changes: 2 additions & 2 deletions src/main/kotlin/no/nav/pdfgen/Application.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ fun Application.module() {
}

data class ApplicationState(
var alive: Boolean = true,
var ready: Boolean = true,
var alive: Boolean = false,
var ready: Boolean = false,
)
7 changes: 6 additions & 1 deletion src/main/kotlin/no/nav/pdfgen/plugins/LifecycleHooks.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import no.nav.pdfgen.ApplicationState

fun Application.configureLifecycleHooks(applicationState: ApplicationState) {

monitor.subscribe(ApplicationStarted) { applicationState.ready = true }
monitor.subscribe(ApplicationStarted) {
applicationState.alive = true
}
monitor.subscribe(ServerReady) {
applicationState.ready = true
}
monitor.subscribe(ApplicationStopped) {
applicationState.ready = false
applicationState.alive = false
Expand Down
56 changes: 45 additions & 11 deletions src/test/kotlin/no/nav/pdfgen/ApplicationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,59 @@ package no.nav.pdfgen

import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.events.*
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.routing.*
import io.ktor.server.testing.*
import no.nav.pdfgen.application.api.nais.registerNaisApi
import no.nav.pdfgen.plugins.configureLifecycleHooks
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

internal class ApplicationTest {

@Test
internal fun `Returns ok on is_alive`() {
internal fun `App is ready only after ServerReady is raised`() {
testApplication {
var raiseApplicationStarted: () -> Any
var raiseServerReady: () -> Any
application {
routing {
val applicationState = ApplicationState()
applicationState.ready = true
applicationState.alive = true
registerNaisApi(applicationState)
configureLifecycleHooks(applicationState)
}
raiseApplicationStarted = { monitor.raise(ApplicationStarted, this) }
raiseServerReady = { monitor.raise(ServerReady, this.environment) }
}
val response = client.get("/internal/is_alive")

assertNotReady()
raiseApplicationStarted()
assertNotReady()
raiseServerReady()
assertReady()
}
}

@Test
internal fun `App is alive after application is started`() {
testApplication {
application {
routing {
val applicationState = ApplicationState()
configureLifecycleHooks(applicationState)
registerNaisApi(applicationState)
}
}
val response = client.get("/internal/is_alive")
assertEquals(HttpStatusCode.OK, response.status)
assertEquals("I'm alive", response.bodyAsText())
}
}

@Test
internal fun `Returns ok in is_ready`() {
internal fun `Returns ok on is_alive`() {
testApplication {
application {
routing {
Expand All @@ -40,10 +64,10 @@ internal class ApplicationTest {
registerNaisApi(applicationState)
}
}
val response = client.get("/internal/is_ready")
val response = client.get("/internal/is_alive")

assertEquals(HttpStatusCode.OK, response.status)
assertEquals("I'm ready", response.bodyAsText())
assertEquals("I'm alive", response.bodyAsText())
}
}

Expand Down Expand Up @@ -76,10 +100,20 @@ internal class ApplicationTest {
registerNaisApi(applicationState)
}
}
val response = client.get("/internal/is_ready")

assertEquals(HttpStatusCode.InternalServerError, response.status)
assertEquals("Please wait! I'm not ready :(", response.bodyAsText())
assertNotReady()
}

}

private suspend fun ApplicationTestBuilder.assertReady() {
val readyResponse = client.get("/internal/is_ready")
assertEquals(HttpStatusCode.OK, readyResponse.status)
assertEquals("I'm ready", readyResponse.bodyAsText())
}

private suspend fun ApplicationTestBuilder.assertNotReady() {
val response = client.get("/internal/is_ready")
assertEquals(HttpStatusCode.InternalServerError, response.status)
assertEquals("Please wait! I'm not ready :(", response.bodyAsText())
}
}

0 comments on commit 832ed16

Please sign in to comment.