[K/N] Performance infra migration tools
This commit is contained in:
committed by
Space Team
parent
b9b2713a96
commit
2767e95c99
File diff suppressed because it is too large
Load Diff
-1494
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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+83
-37
@@ -128,11 +128,8 @@ data class BuildInfo(val buildNumber: String, val startTime: String, val endTime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class ElasticSearchType {
|
abstract class ElasticSearchIndex(indexNameSuffix: String, val connector: ElasticSearchConnector) {
|
||||||
TEXT, KEYWORD, DATE, LONG, DOUBLE, BOOLEAN, OBJECT, NESTED
|
val indexName = "kotlin_native_" + indexNameSuffix
|
||||||
}
|
|
||||||
|
|
||||||
abstract class ElasticSearchIndex(val indexName: String, val connector: ElasticSearchConnector) {
|
|
||||||
// Insert data.
|
// Insert data.
|
||||||
fun insert(data: JsonSerializable): Promise<String> {
|
fun insert(data: JsonSerializable): Promise<String> {
|
||||||
val description = data.toJson()
|
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)
|
return connector.request(RequestMethod.POST, path, body = requestJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract val mapping: Map<String, ElasticSearchType>
|
abstract val createMappingQuery: String
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BenchmarksIndex(name: String, connector: ElasticSearchConnector) : ElasticSearchIndex(name, connector) {
|
class BenchmarksIndex(name: String, connector: ElasticSearchConnector) : ElasticSearchIndex(name, connector) {
|
||||||
override val mapping: Map<String, ElasticSearchType>
|
override val createMappingQuery = """
|
||||||
get() = mapOf("buildNumber" to ElasticSearchType.KEYWORD,
|
PUT /${indexName}
|
||||||
"benchmarks" to ElasticSearchType.NESTED,
|
{
|
||||||
"env" to ElasticSearchType.NESTED,
|
"mappings" : {
|
||||||
"kotlin" to ElasticSearchType.NESTED)
|
"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) {
|
class GoldenResultsIndex(connector: ElasticSearchConnector) : ElasticSearchIndex("golden", connector) {
|
||||||
override val mapping: Map<String, ElasticSearchType>
|
override val createMappingQuery = """
|
||||||
get() = mapOf("buildNumber" to ElasticSearchType.KEYWORD,
|
PUT /${indexName}
|
||||||
"benchmarks" to ElasticSearchType.NESTED,
|
{
|
||||||
"env" to ElasticSearchType.NESTED,
|
"mappings" : {
|
||||||
"kotlin" to ElasticSearchType.NESTED)
|
"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) {
|
class BuildInfoIndex(connector: ElasticSearchConnector) : ElasticSearchIndex("builds", connector) {
|
||||||
override val mapping: Map<String, ElasticSearchType>
|
override val createMappingQuery = """
|
||||||
get() = mapOf("buildNumber" to ElasticSearchType.KEYWORD,
|
PUT /${indexName}
|
||||||
"startTime" to ElasticSearchType.DATE,
|
{
|
||||||
"endTime" to ElasticSearchType.DATE,
|
"mappings" : {
|
||||||
"commits" to ElasticSearchType.NESTED)
|
"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.
|
// Processed benchmark result with calculated mean, variance and normalized reult.
|
||||||
|
|||||||
+2
-1
@@ -31,7 +31,8 @@ class UrlNetworkConnector(private val host: String, private val port: Int? = nul
|
|||||||
json(
|
json(
|
||||||
"method" to method.toString(),
|
"method" to method.toString(),
|
||||||
"headers" to json(*(headers.toTypedArray())),
|
"headers" to json(*(headers.toTypedArray())),
|
||||||
"body" to body
|
"body" to body,
|
||||||
|
"redirect" to "follow",
|
||||||
)
|
)
|
||||||
).then { response ->
|
).then { response ->
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
|||||||
+2
@@ -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.
|
// Golden result value used to get normalized results.
|
||||||
data class GoldenResult(val benchmarkName: String, val metric: String, val value: Double)
|
external interface GoldenResult {
|
||||||
data class GoldenResultsInfo(val goldenResults: Array<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.
|
// Convert information about golden results to benchmarks report format.
|
||||||
fun GoldenResultsInfo.toBenchmarksReport(): BenchmarksReport {
|
fun GoldenResultsInfo.toBenchmarksReport(): BenchmarksReport {
|
||||||
val benchmarksSamples = goldenResults.map {
|
val benchmarksSamples = goldenResults.map {
|
||||||
BenchmarkResult(it.benchmarkName, BenchmarkResult.Status.PASSED,
|
BenchmarkWithStabilityState(it.benchmarkName, BenchmarkResult.Status.PASSED,
|
||||||
it.value, BenchmarkResult.metricFromString(it.metric)!!, it.value, 1, 0)
|
it.value, BenchmarkResult.metricFromString(it.metric)!!, it.value, 1, 0, it.unstable)
|
||||||
}
|
}
|
||||||
val compiler = Compiler(Compiler.Backend(Compiler.BackendType.NATIVE, "golden", emptyList()), "golden")
|
val compiler = Compiler(Compiler.Backend(Compiler.BackendType.NATIVE, "golden", emptyList()), "golden")
|
||||||
val environment = Environment(Environment.Machine("golden", "golden"), Environment.JDKInstance("golden", "golden"))
|
val environment = Environment(Environment.Machine("golden", "golden"), Environment.JDKInstance("golden", "golden"))
|
||||||
return BenchmarksReport(environment,
|
return BenchmarksReport(environment, benchmarksSamples, compiler)
|
||||||
benchmarksSamples, compiler)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build information provided from request.
|
// 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?) {
|
val bundleSize: String?, val fileWithResult: String, val buildNumberSuffix: String?) {
|
||||||
companion object {
|
companion object {
|
||||||
fun create(json: String): BuildRegister {
|
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.
|
// Parse method doesn't create real instance with all methods. So create it by hands.
|
||||||
return BuildRegister(requestDetails.buildId, requestDetails.teamCityUser, requestDetails.teamCityPassword,
|
return BuildRegister(
|
||||||
requestDetails.bundleSize, requestDetails.fileWithResult, requestDetails.buildNumberSuffix)
|
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 goldenIndex = GoldenResultsIndex(connector)
|
||||||
val buildInfoIndex = BuildInfoIndex(connector)
|
val buildInfoIndex = BuildInfoIndex(connector)
|
||||||
|
|
||||||
router.get("/createMapping") { _, response ->
|
router.get("/showMappingsQueries") { _, response ->
|
||||||
buildInfoIndex.createMapping().then { _ ->
|
val queries = listOf(
|
||||||
response.sendStatus(200)
|
buildInfoIndex.createMappingQuery,
|
||||||
}.catch { _ ->
|
goldenIndex.createMappingQuery,
|
||||||
response.sendStatus(400)
|
) + benchmarksDispatcher.createMappingQueries
|
||||||
}
|
response.send(queries.joinToString("\n\n\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get consistent build information in cases of rerunning the same build.
|
// Get consistent build information in cases of rerunning the same build.
|
||||||
@@ -383,7 +394,9 @@ fun router(connector: ElasticSearchConnector) {
|
|||||||
println(errorResponse)
|
println(errorResponse)
|
||||||
reject()
|
reject()
|
||||||
}
|
}
|
||||||
}.catch {
|
}.catch { errorResponse ->
|
||||||
|
println("Error during getting builds")
|
||||||
|
println(errorResponse)
|
||||||
reject()
|
reject()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -632,8 +645,9 @@ fun router(connector: ElasticSearchConnector) {
|
|||||||
CachableResponseDispatcher.getResponse(request, response) { success, reject ->
|
CachableResponseDispatcher.getResponse(request, response) { success, reject ->
|
||||||
getUnstableResults(goldenIndex).then { unstableBenchmarks ->
|
getUnstableResults(goldenIndex).then { unstableBenchmarks ->
|
||||||
success(unstableBenchmarks)
|
success(unstableBenchmarks)
|
||||||
}.catch {
|
}.catch { errorResponse ->
|
||||||
println("Error during getting unstable benchmarks")
|
println("Error during getting unstable benchmarks")
|
||||||
|
println(errorResponse)
|
||||||
reject()
|
reject()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user