Skip to content

Commit

Permalink
test: performance testing for sdk core
Browse files Browse the repository at this point in the history
  • Loading branch information
OmarAlJarrah committed Nov 26, 2024
1 parent ba99751 commit 4dfe4d2
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import com.expediagroup.sdk.performancetest.benchmark.AsyncPostMessageOperationB
import com.expediagroup.sdk.performancetest.benchmark.DownloadOperationBenchmark
import com.expediagroup.sdk.performancetest.benchmark.GetMessageOperationBenchmark
import com.expediagroup.sdk.performancetest.benchmark.PostMessageOperationBenchmark
import com.expediagroup.sdk.performancetest.client.EanBasedClient
import com.expediagroup.sdk.performancetest.client.BasicAuthBasedClient
import com.expediagroup.sdk.performancetest.client.EanAuthBasedClient
import com.expediagroup.sdk.performancetest.common.PerformanceTestClient
import com.expediagroup.sdk.performancetest.common.benchmark.AsyncBenchmarked
import com.expediagroup.sdk.performancetest.common.benchmark.Benchmark
Expand All @@ -45,13 +46,23 @@ class Main {
}
}

private val clients: List<PerformanceTestClient> = listOf(
EanBasedClient.builder()
.key("dummy-key")
.secret("dummy-secret")
.endpoint(System.getProperty("mockServerUrl", "http://localhost:8080"))
.build()
)
private val clients: List<PerformanceTestClient> = buildList {
add(
EanAuthBasedClient.builder()
.key("dummy-key")
.secret("dummy-secret")
.endpoint(System.getProperty("mockServerUrl", "http://localhost:8080"))
.build()
)

add(
BasicAuthBasedClient.builder()
.key("dummy-key")
.secret("dummy-secret")
.endpoint(System.getProperty("mockServerUrl", "http://localhost:8080"))
.build()
)
}

private val syncBenchmarks: List<Benchmarked<*>> = buildList {
clients.forEach { client ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class DownloadOperationBenchmark(
repeat = 10,
timeout = 1,
timeoutUnit = TimeUnit.MINUTES,
description = "Sync File Download Operation Executed 10 times",
description = "Sync File Download Operation Executed 10 times using ${client.javaClass.simpleName} client",
) {
override fun benchmark(): Response<InputStream> {
return client.execute(DownloadFileOperation())
Expand All @@ -46,7 +46,7 @@ class AsyncDownloadOperationBenchmark(
repeat = 1000,
timeout = 1,
timeoutUnit = TimeUnit.HOURS,
description = "Async File Download Operation Executed 1000 times",
description = "Async File Download Operation Executed 1000 times using ${client.javaClass.simpleName} client",
) {
override fun benchmarkAsync(): CompletableFuture<Response<InputStream>> {
return client.executeAsync(DownloadFileOperation())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class GetMessageOperationBenchmark(
repeat = 10,
timeout = 1,
timeoutUnit = TimeUnit.MINUTES,
description = "Sync Get Message Operation Executed 10 times"
description = "Sync Get Message Operation Executed 10 times using ${client.javaClass.simpleName} client"
) {
override fun benchmark(): Response<Message> {
return client.execute(GetMessageOperation())
Expand All @@ -46,7 +46,7 @@ class AsyncGetMessageOperationBenchmark(
repeat = 1000,
timeout = 1,
timeoutUnit = TimeUnit.HOURS,
description = "Async Get Message Operation Executed 1000 times"
description = "Async Get Message Operation Executed 1000 times using ${client.javaClass.simpleName} client"
) {
override fun benchmarkAsync(): CompletableFuture<Response<Message>> {
return client.executeAsync(GetMessageOperation())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class PostMessageOperationBenchmark(
repeat = 10,
timeout = 1,
timeoutUnit = TimeUnit.MINUTES,
description = "Sync Post Message Operation Executed 10 times"
description = "Sync Post Message Operation Executed 10 times using ${client.javaClass.simpleName} client"
) {
override fun benchmark(): Response<Message> {
return client.execute(PostMessageOperation(Message("Hello, World!".repeat(1e6.toInt()))))
Expand All @@ -47,7 +47,7 @@ class AsyncPostMessageOperationBenchmark(
repeat = 1000,
timeout = 1,
timeoutUnit = TimeUnit.HOURS,
description = "Async Post Message Operation Executed 1000 times"
description = "Async Post Message Operation Executed 1000 times using ${client.javaClass.simpleName} client"
) {
override fun benchmarkAsync(): CompletableFuture<Response<Message>> {
return client.executeAsync(PostMessageOperation(Message("Hello, World!".repeat(1e6.toInt()))))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package com.expediagroup.sdk.performancetest.client

import com.expediagroup.sdk.core.client.BaseXapClient
import com.expediagroup.sdk.core.configuration.XapClientConfiguration
import com.expediagroup.sdk.core.model.EmptyResponse
import com.expediagroup.sdk.core.model.Nothing
import com.expediagroup.sdk.core.model.Operation
import com.expediagroup.sdk.core.model.Response
import com.expediagroup.sdk.core.model.exception.handle
import com.expediagroup.sdk.performancetest.common.PerformanceTestClient
import com.expediagroup.sdk.performancetest.common.model.Message
import com.expediagroup.sdk.performancetest.common.operation.DownloadFileOperation
import com.expediagroup.sdk.performancetest.common.operation.GetMessageOperation
import com.expediagroup.sdk.performancetest.common.operation.PostMessageOperation
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.future.future
import java.io.InputStream
import java.util.concurrent.CompletableFuture

class BasicAuthBasedClient(
clientConfiguration: XapClientConfiguration
) : PerformanceTestClient, BaseXapClient(
namespace = "ean",
clientConfiguration = clientConfiguration
) {
companion object {
@JvmStatic
fun builder() = Builder()
}

private suspend inline fun <reified RequestType> executeHttpRequest(operation: Operation<RequestType>): HttpResponse {
return httpClient.request {
method = HttpMethod.parse(operation.method)
url(operation.url)

operation.params?.getHeaders()?.let {
headers.appendAll(it)
}

operation.params?.getQueryParams()?.let {
url.parameters.appendAll(it)
}

contentType(ContentType.Application.Json)
setBody(operation.requestBody)
}
}

private inline fun <reified RequestType> executeAsyncWithEmptyResponse(operation: Operation<RequestType>): CompletableFuture<EmptyResponse> {
return GlobalScope.future(Dispatchers.IO) {
try {
val response = executeHttpRequest(operation)
throwIfError(response, operation.operationId)
EmptyResponse(response.status.value, response.headers.entries())
} catch (exception: Exception) {
exception.handle()
}
}
}

private inline fun <reified RequestType, reified ResponseType> execute(operation: Operation<RequestType>): Response<ResponseType> {
try {
return executeAsync<RequestType, ResponseType>(operation).get()
} catch (exception: Exception) {
exception.handle()
}
}

private inline fun <reified RequestType, reified ResponseType> executeAsync(operation: Operation<RequestType>): CompletableFuture<Response<ResponseType>> {
return GlobalScope.future(Dispatchers.IO) {
try {
val response = executeHttpRequest(operation)
throwIfError(response, operation.operationId)
Response(response.status.value, response.body<ResponseType>(), response.headers.entries())
} catch (exception: Exception) {
exception.handle()
}
}
}

override fun execute(operation: DownloadFileOperation): Response<InputStream> {
return execute<Nothing, InputStream>(operation)
}

override fun executeAsync(operation: DownloadFileOperation): CompletableFuture<Response<InputStream>> {
return executeAsync<Nothing, InputStream>(operation)
}

override fun execute(operation: GetMessageOperation): Response<Message> {
return execute<Nothing, Message>(operation)
}

override fun executeAsync(operation: GetMessageOperation): CompletableFuture<Response<Message>> {
return executeAsync<Nothing, Message>(operation)
}

override fun execute(operation: PostMessageOperation): Response<Message> {
return execute<Message, Message>(operation)
}

override fun executeAsync(operation: PostMessageOperation): CompletableFuture<Response<Message>> {
return executeAsync<Message, Message>(operation)
}

override suspend fun throwServiceException(response: HttpResponse, operationId: String) {
throw Exception("Service exception occurred for operation $operationId with status code ${response.status.value}")
}

class Builder : BaseXapClient.Builder<Builder>() {
override fun build() =
BasicAuthBasedClient(
XapClientConfiguration(key, secret, endpoint, requestTimeout, connectionTimeout, socketTimeout, maskedLoggingHeaders, maskedLoggingBodyFields)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import kotlinx.coroutines.future.future
import java.io.InputStream
import java.util.concurrent.CompletableFuture

class EanBasedClient(
class EanAuthBasedClient(
clientConfiguration: RapidClientConfiguration
) : PerformanceTestClient, BaseRapidClient(
namespace = "ean",
Expand Down Expand Up @@ -129,7 +129,7 @@ class EanBasedClient(

class Builder : BaseRapidClient.Builder<Builder>() {
override fun build() =
EanBasedClient(
EanAuthBasedClient(
RapidClientConfiguration(key, secret, endpoint, requestTimeout, connectionTimeout, socketTimeout, maskedLoggingHeaders, maskedLoggingBodyFields)
)
}
Expand Down

0 comments on commit 4dfe4d2

Please sign in to comment.