[K/N] Performance infra migration tools

This commit is contained in:
Pavel Kunyavskiy
2022-10-25 14:23:14 +02:00
committed by Space Team
parent b9b2713a96
commit 2767e95c99
7 changed files with 1131 additions and 1565 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,16 +0,0 @@
{
"name": "performance-server",
"version": "1.0.0",
"main": "server/app.js",
"scripts": {
"start": "node server/app.js"
},
"dependencies": {
"body-parser": "~1.20.0",
"debug": "~4.3.4",
"ejs": "~3.1.7",
"express": "~4.18.1",
"kotlin": "~1.6.20",
"node-fetch": "~2.6.6"
}
}
@@ -128,11 +128,8 @@ data class BuildInfo(val buildNumber: String, val startTime: String, val endTime
}
}
enum class ElasticSearchType {
TEXT, KEYWORD, DATE, LONG, DOUBLE, BOOLEAN, OBJECT, NESTED
}
abstract class ElasticSearchIndex(val indexName: String, val connector: ElasticSearchConnector) {
abstract class ElasticSearchIndex(indexNameSuffix: String, val connector: ElasticSearchConnector) {
val indexName = "kotlin_native_" + indexNameSuffix
// Insert data.
fun insert(data: JsonSerializable): Promise<String> {
val description = data.toJson()
@@ -153,47 +150,96 @@ abstract class ElasticSearchIndex(val indexName: String, val connector: ElasticS
return connector.request(RequestMethod.POST, path, body = requestJson)
}
abstract val mapping: Map<String, ElasticSearchType>
val mappingDescription: String
get() = """
{
"mappings": {
"properties": {
${mapping.map { (property, type) ->
"\"${property}\": { \"type\": \"${type.name.lowercase()}\"${if (type == ElasticSearchType.DATE) "," +
"\"format\": \"basic_date_time_no_millis\"" else ""} }"
}.joinToString()}}
}
}
""".trimIndent()
fun createMapping() =
connector.request(RequestMethod.PUT, indexName, body = mappingDescription)
abstract val createMappingQuery: String
}
class BenchmarksIndex(name: String, connector: ElasticSearchConnector) : ElasticSearchIndex(name, connector) {
override val mapping: Map<String, ElasticSearchType>
get() = mapOf("buildNumber" to ElasticSearchType.KEYWORD,
"benchmarks" to ElasticSearchType.NESTED,
"env" to ElasticSearchType.NESTED,
"kotlin" to ElasticSearchType.NESTED)
override val createMappingQuery = """
PUT /${indexName}
{
"mappings" : {
"properties" : {
"benchmarks" : {
"type" : "nested",
"properties": {
"metric": { "type": "keyword" },
"name": { "type": "keyword" },
"normalizedScore": { "type": "float" }
"repeat": { "type": "long" },
"runtimeInUs": { "type": "float" },
"score": { "type": "float" },
"status": { "type": "keyword" },
"variance": { "type": "float" },
"warmup": { "type": "long" },
}
},
"buildNumber" : { "type" : "keyword" },
"env" : { "type" : "nested" },
"kotlin" : { "type" : "nested" }
}
}
}
}
""".trimIndent()
}
class GoldenResultsIndex(connector: ElasticSearchConnector) : ElasticSearchIndex("golden", connector) {
override val mapping: Map<String, ElasticSearchType>
get() = mapOf("buildNumber" to ElasticSearchType.KEYWORD,
"benchmarks" to ElasticSearchType.NESTED,
"env" to ElasticSearchType.NESTED,
"kotlin" to ElasticSearchType.NESTED)
override val createMappingQuery = """
PUT /${indexName}
{
"mappings" : {
"properties" : {
"benchmarks" : {
"type" : "nested",
"properties" : {
"metric" : { "type" : "keyword" },
"name" : { "type" : "keyword" },
"repeat" : { "type" : "long" },
"runtimeInUs" : { "type" : "double" },
"score" : { "type" : "double" },
"status" : { "type" : "keyword" },
"unstable" : { "type" : "boolean" },
"warmup" : { "type" : "long" }
}
},
"buildNumber" : { "type" : "keyword" },
"env" : { "type" : "nested"},
"kotlin" : { "type" : "nested" }
}
}
}
""".trimIndent()
}
class BuildInfoIndex(connector: ElasticSearchConnector) : ElasticSearchIndex("builds", connector) {
override val mapping: Map<String, ElasticSearchType>
get() = mapOf("buildNumber" to ElasticSearchType.KEYWORD,
"startTime" to ElasticSearchType.DATE,
"endTime" to ElasticSearchType.DATE,
"commits" to ElasticSearchType.NESTED)
override val createMappingQuery = """
PUT /${indexName}
{
"mappings" : {
"properties" : {
"agentInfo" : { "type" : "keyword" },
"branch" : { "type" : "keyword" },
"buildNumber" : { "type" : "keyword" },
"buildType" : { "type" : "keyword" },
"commits" : {
"type" : "nested",
"properties" : {
"developer" : { "type" : "text" },
"revision" : { "type" : "text" }
}
},
"endTime" : {
"type" : "date",
"format" : "basic_date_time_no_millis"
},
"startTime" : {
"type" : "date",
"format" : "basic_date_time_no_millis"
}
}
}
}
""".trimIndent()
}
// Processed benchmark result with calculated mean, variance and normalized reult.
@@ -31,7 +31,8 @@ class UrlNetworkConnector(private val host: String, private val port: Int? = nul
json(
"method" to method.toString(),
"headers" to json(*(headers.toTypedArray())),
"body" to body
"body" to body,
"redirect" to "follow",
)
).then { response ->
if (!response.ok) {
@@ -380,4 +380,6 @@ class BenchmarksIndexesDispatcher(connector: ElasticSearchConnector, val feature
)
}
}
val createMappingQueries get() = benchmarksIndexes.values.map { it.createMappingQuery }
}
@@ -85,19 +85,25 @@ internal fun convert(json: String, buildNumber: String, target: String): List<Be
}
// Golden result value used to get normalized results.
data class GoldenResult(val benchmarkName: String, val metric: String, val value: Double)
data class GoldenResultsInfo(val goldenResults: Array<GoldenResult>)
external interface GoldenResult {
val benchmarkName: String
val metric: String
val value: Double
val unstable: Boolean
}
external interface GoldenResultsInfo {
val goldenResults: Array<GoldenResult>
}
// Convert information about golden results to benchmarks report format.
fun GoldenResultsInfo.toBenchmarksReport(): BenchmarksReport {
val benchmarksSamples = goldenResults.map {
BenchmarkResult(it.benchmarkName, BenchmarkResult.Status.PASSED,
it.value, BenchmarkResult.metricFromString(it.metric)!!, it.value, 1, 0)
BenchmarkWithStabilityState(it.benchmarkName, BenchmarkResult.Status.PASSED,
it.value, BenchmarkResult.metricFromString(it.metric)!!, it.value, 1, 0, it.unstable)
}
val compiler = Compiler(Compiler.Backend(Compiler.BackendType.NATIVE, "golden", emptyList()), "golden")
val environment = Environment(Environment.Machine("golden", "golden"), Environment.JDKInstance("golden", "golden"))
return BenchmarksReport(environment,
benchmarksSamples, compiler)
return BenchmarksReport(environment, benchmarksSamples, compiler)
}
// Build information provided from request.
@@ -108,10 +114,15 @@ data class BuildRegister(val buildId: String, val teamCityUser: String, val team
val bundleSize: String?, val fileWithResult: String, val buildNumberSuffix: String?) {
companion object {
fun create(json: String): BuildRegister {
val requestDetails = JSON.parse<BuildRegister>(json)
val requestDetails = JSON.parse<dynamic>(json)
// Parse method doesn't create real instance with all methods. So create it by hands.
return BuildRegister(requestDetails.buildId, requestDetails.teamCityUser, requestDetails.teamCityPassword,
requestDetails.bundleSize, requestDetails.fileWithResult, requestDetails.buildNumberSuffix)
return BuildRegister(
requestDetails.buildId,
requestDetails.teamCityUser,
requestDetails.teamCityPassword,
requestDetails.bundleSize,
requestDetails.fileWithResult,
requestDetails.buildNumberSuffix)
}
}
@@ -230,12 +241,12 @@ fun router(connector: ElasticSearchConnector) {
val goldenIndex = GoldenResultsIndex(connector)
val buildInfoIndex = BuildInfoIndex(connector)
router.get("/createMapping") { _, response ->
buildInfoIndex.createMapping().then { _ ->
response.sendStatus(200)
}.catch { _ ->
response.sendStatus(400)
}
router.get("/showMappingsQueries") { _, response ->
val queries = listOf(
buildInfoIndex.createMappingQuery,
goldenIndex.createMappingQuery,
) + benchmarksDispatcher.createMappingQueries
response.send(queries.joinToString("\n\n\n"))
}
// Get consistent build information in cases of rerunning the same build.
@@ -383,7 +394,9 @@ fun router(connector: ElasticSearchConnector) {
println(errorResponse)
reject()
}
}.catch {
}.catch { errorResponse ->
println("Error during getting builds")
println(errorResponse)
reject()
}
}
@@ -632,8 +645,9 @@ fun router(connector: ElasticSearchConnector) {
CachableResponseDispatcher.getResponse(request, response) { success, reject ->
getUnstableResults(goldenIndex).then { unstableBenchmarks ->
success(unstableBenchmarks)
}.catch {
}.catch { errorResponse ->
println("Error during getting unstable benchmarks")
println(errorResponse)
reject()
}
}