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