Skip to content

Commit c50c9b4

Browse files
committed
More tests
1 parent ef33a73 commit c50c9b4

File tree

11 files changed

+434
-154
lines changed

11 files changed

+434
-154
lines changed

lambda-runtime/build.gradle.kts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44
alias(libs.plugins.kotlin.multiplatform)
55
alias(libs.plugins.kotlin.serialization)
66
alias(libs.plugins.mokkery)
7-
alias(libs.plugins.allopen)
7+
alias(libs.plugins.kotlinx.resources)
88
}
99

1010
kotlin {
@@ -31,20 +31,15 @@ kotlin {
3131
}
3232

3333
nativeTest.dependencies {
34+
implementation(projects.lambdaEvents)
3435
implementation(libs.kotlin.test)
3536
implementation(libs.kotlin.coroutines.test)
3637
implementation(libs.ktor.client.mock)
38+
implementation(libs.kotlinx.resources)
3739
}
3840
}
3941
}
4042

41-
fun isTestingTask(name: String) = name.endsWith("Test")
42-
val isTesting = gradle.startParameter.taskNames.any(::isTestingTask)
43-
44-
if (isTesting) allOpen {
45-
annotation("kotlin.Metadata")
46-
}
47-
4843
mokkery {
4944
defaultMockMode.set(MockMode.autoUnit)
5045
}

lambda-runtime/src/commonMain/kotlin/io/github/trueangle/knative/lambda/runtime/Ext.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ internal fun Throwable.prettyPrint(includeStackTrace: Boolean = true) = buildStr
1111
}
1212
}
1313

14-
internal fun <T> unsafeLazy(initializer: () -> T): Lazy<T> = lazy(LazyThreadSafetyMode.NONE, initializer)
14+
internal fun <T> unsafeLazy(initializer: () -> T): Lazy<T> = lazy(LazyThreadSafetyMode.NONE, initializer)

lambda-runtime/src/commonMain/kotlin/io/github/trueangle/knative/lambda/runtime/LambdaEnvironment.kt

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,40 @@ import io.github.trueangle.knative.lambda.runtime.ReservedRuntimeEnvironmentVari
1111
import kotlinx.cinterop.ExperimentalForeignApi
1212
import kotlinx.cinterop.toKString
1313
import platform.posix.getenv
14+
import kotlin.system.exitProcess
1415

15-
@OptIn(ExperimentalForeignApi::class)
1616
@PublishedApi
17-
internal object LambdaEnvironment {
18-
val FUNCTION_MEMORY_SIZE by unsafeLazy {
19-
getenv(AWS_LAMBDA_FUNCTION_MEMORY_SIZE)?.toKString()?.toIntOrNull() ?: 128
20-
}
21-
val LOG_GROUP_NAME by unsafeLazy {
22-
getenv(AWS_LAMBDA_LOG_GROUP_NAME)?.toKString().orEmpty()
23-
}
24-
val LOG_STREAM_NAME by unsafeLazy {
25-
getenv(AWS_LAMBDA_LOG_STREAM_NAME)?.toKString().orEmpty()
26-
}
27-
val LAMBDA_LOG_LEVEL by unsafeLazy {
28-
getenv(AWS_LAMBDA_LOG_LEVEL)?.toKString() ?: "INFO"
29-
}
30-
val LAMBDA_LOG_FORMAT by unsafeLazy {
31-
getenv(AWS_LAMBDA_LOG_FORMAT)?.toKString() ?: "TEXT"
32-
}
33-
val FUNCTION_NAME by unsafeLazy {
34-
getenv(AWS_LAMBDA_FUNCTION_NAME)?.toKString().orEmpty()
35-
}
36-
val FUNCTION_VERSION by unsafeLazy {
37-
getenv(AWS_LAMBDA_FUNCTION_VERSION)?.toKString().orEmpty()
38-
}
39-
val RUNTIME_API by unsafeLazy {
40-
getenv(AWS_LAMBDA_RUNTIME_API)?.toKString()
17+
internal open class LambdaEnvironment {
18+
// open due to Mokkery limits
19+
open fun terminate(): Nothing = exitProcess(1)
20+
21+
@OptIn(ExperimentalForeignApi::class)
22+
@PublishedApi
23+
internal companion object Variables {
24+
val FUNCTION_MEMORY_SIZE by unsafeLazy {
25+
getenv(AWS_LAMBDA_FUNCTION_MEMORY_SIZE)?.toKString()?.toIntOrNull() ?: 128
26+
}
27+
val LOG_GROUP_NAME by unsafeLazy {
28+
getenv(AWS_LAMBDA_LOG_GROUP_NAME)?.toKString().orEmpty()
29+
}
30+
val LOG_STREAM_NAME by unsafeLazy {
31+
getenv(AWS_LAMBDA_LOG_STREAM_NAME)?.toKString().orEmpty()
32+
}
33+
val LAMBDA_LOG_LEVEL by unsafeLazy {
34+
getenv(AWS_LAMBDA_LOG_LEVEL)?.toKString() ?: "INFO"
35+
}
36+
val LAMBDA_LOG_FORMAT by unsafeLazy {
37+
getenv(AWS_LAMBDA_LOG_FORMAT)?.toKString() ?: "TEXT"
38+
}
39+
val FUNCTION_NAME by unsafeLazy {
40+
getenv(AWS_LAMBDA_FUNCTION_NAME)?.toKString().orEmpty()
41+
}
42+
val FUNCTION_VERSION by unsafeLazy {
43+
getenv(AWS_LAMBDA_FUNCTION_VERSION)?.toKString().orEmpty()
44+
}
45+
val RUNTIME_API by unsafeLazy {
46+
getenv(AWS_LAMBDA_RUNTIME_API)?.toKString()
47+
}
4148
}
4249
}
4350

lambda-runtime/src/commonMain/kotlin/io/github/trueangle/knative/lambda/runtime/LambdaRuntime.kt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package io.github.trueangle.knative.lambda.runtime
33
import io.github.trueangle.knative.lambda.runtime.LambdaEnvironmentException.NonRecoverableStateException
44
import io.github.trueangle.knative.lambda.runtime.api.Context
55
import io.github.trueangle.knative.lambda.runtime.api.LambdaClient
6+
import io.github.trueangle.knative.lambda.runtime.api.LambdaClientImpl
67
import io.github.trueangle.knative.lambda.runtime.handler.LambdaBufferedHandler
78
import io.github.trueangle.knative.lambda.runtime.handler.LambdaHandler
89
import io.github.trueangle.knative.lambda.runtime.handler.LambdaStreamHandler
@@ -29,15 +30,14 @@ import io.ktor.utils.io.writeStringUtf8
2930
import kotlinx.coroutines.runBlocking
3031
import kotlinx.serialization.ExperimentalSerializationApi
3132
import kotlinx.serialization.json.Json
32-
import kotlin.system.exitProcess
3333

3434
object LambdaRuntime {
3535
@OptIn(ExperimentalSerializationApi::class)
3636
internal val json = Json { explicitNulls = false }
3737

3838
inline fun <reified I, reified O> run(crossinline initHandler: () -> LambdaHandler<I, O>) = runBlocking {
3939
val curlHttpClient = createHttpClient(Curl.create())
40-
val lambdaClient = LambdaClient(curlHttpClient)
40+
val lambdaClient = LambdaClientImpl(curlHttpClient)
4141

4242
Runner(client = lambdaClient, log = Log).run(false, initHandler)
4343
}
@@ -59,7 +59,8 @@ object LambdaRuntime {
5959
@PublishedApi
6060
internal class Runner(
6161
val client: LambdaClient,
62-
val log: LambdaLogger
62+
val log: LambdaLogger,
63+
val env: LambdaEnvironment = LambdaEnvironment()
6364
) {
6465
suspend inline fun <reified I, reified O> run(singleEventMode: Boolean = false, crossinline initHandler: () -> LambdaHandler<I, O>) {
6566
val handler = try {
@@ -70,7 +71,8 @@ internal class Runner(
7071
log.fatal(e)
7172

7273
client.reportError(e.asInitError())
73-
exitProcess(1)
74+
75+
env.terminate()
7476
}
7577

7678
val handlerName = handler::class.simpleName
@@ -116,15 +118,15 @@ internal class Runner(
116118
is NonRecoverableStateException -> {
117119
log.fatal(e)
118120

119-
exitProcess(1)
121+
env.terminate()
120122
}
121123

122124
else -> log.error(e)
123125
}
124126
} catch (e: Throwable) {
125127
log.fatal(e)
126128

127-
exitProcess(1)
129+
env.terminate()
128130
}
129131

130132
if (singleEventMode) {

lambda-runtime/src/commonMain/kotlin/io/github/trueangle/knative/lambda/runtime/api/LambdaRuntimeClient.kt

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,22 @@ import kotlin.time.Duration.Companion.minutes
2727
import io.ktor.http.ContentType.Application.Json as ContentTypeJson
2828

2929
@PublishedApi
30-
internal class LambdaClient(private val httpClient: HttpClient) {
30+
internal interface LambdaClient {
31+
suspend fun <T> retrieveNextEvent(bodyType: TypeInfo): Pair<T, Context>
32+
suspend fun <T> sendResponse(event: Context, body: T, bodyType: TypeInfo): HttpResponse
33+
suspend fun streamResponse(event: Context, outgoingContent: OutgoingContent): HttpResponse
34+
suspend fun reportError(error: LambdaRuntimeException)
35+
}
36+
37+
@PublishedApi
38+
internal class LambdaClientImpl(private val httpClient: HttpClient): LambdaClient {
3139
private val baseUrl = requireNotNull(LambdaEnvironment.RUNTIME_API) {
3240
"Can't find AWS_LAMBDA_RUNTIME_API env variable"
3341
}
3442
private val invokeUrl = "http://$baseUrl/2018-06-01/runtime"
3543
private val requestTimeout = 15.minutes.inWholeMilliseconds
3644

37-
suspend fun <T> retrieveNextEvent(bodyType: TypeInfo): Pair<T, Context> {
45+
override suspend fun <T> retrieveNextEvent(bodyType: TypeInfo): Pair<T, Context> {
3846
val response = httpClient.get {
3947
url("${invokeUrl}/invocation/next")
4048

@@ -50,7 +58,7 @@ internal class LambdaClient(private val httpClient: HttpClient) {
5058
return body to context
5159
}
5260

53-
suspend fun <T> sendResponse(event: Context, body: T, bodyType: TypeInfo): HttpResponse {
61+
override suspend fun <T> sendResponse(event: Context, body: T, bodyType: TypeInfo): HttpResponse {
5462
val response = httpClient.post {
5563
url("${invokeUrl}/invocation/${event.awsRequestId}/response")
5664
contentType(ContentTypeJson)
@@ -67,7 +75,7 @@ internal class LambdaClient(private val httpClient: HttpClient) {
6775
return validateResponse(response)
6876
}
6977

70-
suspend fun streamResponse(event: Context, outgoingContent: OutgoingContent): HttpResponse {
78+
override suspend fun streamResponse(event: Context, outgoingContent: OutgoingContent): HttpResponse {
7179
val response = httpClient.post {
7280
url("${invokeUrl}/invocation/${event.awsRequestId}/response")
7381

@@ -92,13 +100,15 @@ internal class LambdaClient(private val httpClient: HttpClient) {
92100
return response
93101
}
94102

95-
suspend fun reportError(error: LambdaRuntimeException) {
96-
val response = when (error) {
103+
override suspend fun reportError(error: LambdaRuntimeException) {
104+
when (error) {
97105
is LambdaRuntimeException.Init -> sendInitError(error)
98-
is LambdaRuntimeException.Invocation -> sendInvocationError(error)
99-
}
106+
is LambdaRuntimeException.Invocation -> {
107+
val response = sendInvocationError(error)
100108

101-
validateResponse(response)
109+
validateResponse(response)
110+
}
111+
}
102112
}
103113

104114
private suspend fun sendInvocationError(

lambda-runtime/src/commonMain/kotlin/io/github/trueangle/knative/lambda/runtime/log/LogLevel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ enum class LogLevel {
2929

3030
companion object {
3131
fun fromEnv(): LogLevel {
32-
val level = LambdaEnvironment.LAMBDA_LOG_LEVEL ?: "INFO"
32+
val level = LambdaEnvironment.LAMBDA_LOG_LEVEL
3333
return runCatching {
3434
valueOf(level)
3535
}.getOrElse {

lambda-runtime/src/nativeTest/kotlin/io/github/trueangle/knative/lambda/runtime/JsonLogFormatterTest.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,5 @@ class JsonLogFormatterTest {
101101
assertEquals(expected, actual)
102102
}
103103

104-
@Serializable
105-
private data class SampleObject(val hello: String)
106104
private data class NonSerialObject(val hello: String)
107105
}

lambda-runtime/src/nativeTest/kotlin/io/github/trueangle/knative/lambda/runtime/LambdaRunnerTest.kt

Lines changed: 0 additions & 101 deletions
This file was deleted.

0 commit comments

Comments
 (0)