From 4c82398ac080339aea5a68eb8dc3448a01336018 Mon Sep 17 00:00:00 2001 From: Claude Brisson Date: Mon, 25 Mar 2024 14:55:56 +0100 Subject: [PATCH] Add load test --- api-webapp/pom.xml | 6 ++ api-webapp/src/test/kotlin/LoadTest.kt | 96 ++++++++++++++++++++++++++ pom.xml | 2 +- 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 api-webapp/src/test/kotlin/LoadTest.kt diff --git a/api-webapp/pom.xml b/api-webapp/pom.xml index 0b08757..1dcf37f 100644 --- a/api-webapp/pom.xml +++ b/api-webapp/pom.xml @@ -292,6 +292,12 @@ 4.1.0 test + + org.ajbrown + name-machine + 1.1.0 + test + com.icegreen diff --git a/api-webapp/src/test/kotlin/LoadTest.kt b/api-webapp/src/test/kotlin/LoadTest.kt new file mode 100644 index 0000000..10385f6 --- /dev/null +++ b/api-webapp/src/test/kotlin/LoadTest.kt @@ -0,0 +1,96 @@ +package org.jeudego.pairgoth.test + +import com.republicate.kson.Json +import org.ajbrown.namemachine.NameGenerator +import org.ajbrown.namemachine.NameGeneratorOptions +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import kotlin.random.Random + +class LoadTest: TestBase() { + + companion object { + val PLAYERS = 1500 + val ROUNDS = 10 + val SKIP_RATIO = 0.1 // 10% + + private val nameGenerator = NameGenerator( + NameGeneratorOptions().apply { + randomSeed = 123456L + } + ) + private val rand = Random(123456L) + private fun generateRating() = rand.nextInt(-900, 2800) + private val countries = listOf("at", "be", "ca", "ch", "cz", "de", "dk", "dz", "ee", "es", "fi", "fr", "ga", "gb", "gr", "hr", "hu", "ie", "il", "in", "it", "jp", "ke", "kh", "kr", "lt", "ma", "ml", "nl", "no", "pl", "pt", "ro", "rs", "ru", "rw", "se", "si", "sk", "sn", "tn", "tr", "tw", "ua", "ug", "us", "vn", "za", "zm") + fun generatePlayer(): Json.Object { + val name = nameGenerator.generateName() + val rating = generateRating() + return Json.Object( + "name" to name.lastName, + "firstname" to name.firstName, + "country" to countries.random(rand), + "club" to "cl${rand.nextInt(100)}", + "rating" to rating, + "rank" to (rating - 2050)/100, + "final" to true, + "skip" to (1..ROUNDS).map { + rand.nextDouble() < SKIP_RATIO + }.mapIndexedNotNullTo(Json.MutableArray()) { index, skip -> + if (skip) index else null + } + ) + } + } + + @Disabled("meant to be run manually") + @Test + fun testVeryBigTournament() { + val before = System.currentTimeMillis() + try { + val tour = TestAPI.post("/api/tour", Json.Object( + "type" to "INDIVIDUAL", + "name" to "Mon Tournoi", + "shortName" to "mon-tournoi", + "startDate" to "2023-05-10", + "endDate" to "2023-05-12", + "country" to "FR", + "location" to "Marseille", + "online" to false, + "timeSystem" to Json.Object( + "type" to "FISCHER", + "mainTime" to 1200, + "increment" to 10 + ), + "rounds" to ROUNDS, + "pairing" to Json.Object( + "type" to "MAC_MAHON", + "handicap" to Json.Object( + "correction" to 1 + ) + ) + )).asObject().getInt("id")!! + repeat(PLAYERS) { + TestAPI.post("/api/tour/$tour/part", generatePlayer()) + } + repeat(ROUNDS) { + val round = it + 1 + val resp = TestAPI.post("/api/tour/$tour/pair/$round", Json.Array("all")) + if (!resp.isArray) { + throw Error(resp.toString()) + } + val games = resp.asArray() + games.map { (it as Json.Object).getInt("id")!! }.forEach { gameId -> + TestAPI.put("/api/tour/$tour/res/$round", Json.Object( + "id" to gameId, + "result" to if (rand.nextBoolean()) "w" else "b" + )) + } + } + val standings = TestAPI.get("/api/tour/$tour/standings/$ROUNDS") + logger.info(standings.toString()) + } finally { + val after = System.currentTimeMillis() + logger.info("testVeryBigTournament ran in ${(after - before) / 1000} seconds") + } + } +} diff --git a/pom.xml b/pom.xml index c111d06..551b363 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ republicate.com https://republicate.com/maven2 - false + true true