tests: improved load tests (added finish step in result table, fixed outdated game data)

This commit is contained in:
Oleg Agafonov 2025-02-04 12:26:24 +04:00
parent 3405b51aaf
commit 2b659cd72c
2 changed files with 40 additions and 17 deletions

View file

@ -7,6 +7,7 @@ import mage.remote.Session;
import mage.view.*;
import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.junit.Assert;
import java.util.List;
import java.util.UUID;
@ -33,7 +34,7 @@ public class LoadCallbackClient implements CallbackClient {
private final String logsPrefix;
private final Boolean showLogsAsHtml; // original game logs in HTML, but it can be converted to txt for more readable console
private String globalProgress = ""; // progress 33% [=20, +21, +17], AI game #9: ---
private String globalProgress = ""; // progress 33% [=20.cd, +21, +17], AI game #9: ---
public LoadCallbackClient(boolean joinGameChat, String logsPrefix, Boolean showLogsAsHtml) {
this.joinGameChat = joinGameChat;
@ -74,6 +75,12 @@ public class LoadCallbackClient implements CallbackClient {
}
break;
case GAME_UPDATE:
GameView newGameView = (GameView) callback.getData();
Assert.assertNotNull("game update event must return game view object", newGameView);
this.gameView = newGameView;
break;
case CHATMESSAGE: {
ChatMessage message = (ChatMessage) callback.getData();
String mes = this.showLogsAsHtml ? message.getMessage() : Jsoup.parse(message.getMessage()).text();
@ -94,7 +101,7 @@ public class LoadCallbackClient implements CallbackClient {
case GAME_UPDATE_AND_INFORM:
case GAME_INFORM_PERSONAL: {
GameClientMessage message = (GameClientMessage) callback.getData();
gameView = message.getGameView();
this.gameView = message.getGameView();
// ignore play priority log
break;
}
@ -174,7 +181,6 @@ public class LoadCallbackClient implements CallbackClient {
break;
// skip callbacks (no need to react)
case GAME_UPDATE:
case JOINED_TABLE:
break;

View file

@ -250,7 +250,11 @@ public class LoadTest {
TableView checkGame = monitor.getTable(tableId).orElse(null);
TableState state = (checkGame == null ? null : checkGame.getTableState());
tasksProgress.update(taskNumber, state == TableState.FINISHED, gameView == null ? 0 : gameView.getTurn());
String finishInfo = "";
if (state == TableState.FINISHED) {
finishInfo = gameView == null ? "??" : gameView.getStep().getStepShortText().toLowerCase(Locale.ENGLISH);
}
tasksProgress.update(taskNumber, finishInfo, gameView == null ? 0 : gameView.getTurn());
String globalProgress = tasksProgress.getInfo();
monitor.client.updateGlobalProgress(globalProgress);
@ -321,7 +325,7 @@ public class LoadTest {
long randomSeed = RandomUtil.nextInt();
LoadTestGameResult gameResult = gameResults.createGame(0, "test game", randomSeed);
TasksProgress tasksProgress = new TasksProgress();
tasksProgress.update(1, false, 0);
tasksProgress.update(1, "", 0);
playTwoAIGame("Single AI game", 1, tasksProgress, randomSeed, "WGUBR", TEST_AI_RANDOM_DECK_SETS, gameResult);
printGameResults(gameResults);
@ -361,7 +365,7 @@ public class LoadTest {
TasksProgress tasksProgress = new TasksProgress();
for (int i = 0; i < seedsList.size(); i++) {
int gameIndex = i;
tasksProgress.update(gameIndex + 1, false, 0);
tasksProgress.update(gameIndex + 1, "", 0);
long randomSeed = seedsList.get(i);
logger.info("Game " + (i + 1) + " of " + seedsList.size() + ", RANDOM seed: " + randomSeed);
Future gameTask = executerService.submit(() -> {
@ -586,11 +590,11 @@ public class LoadTest {
private static class TasksProgress {
private String info;
private final Map<Integer, Boolean> finishes = new LinkedHashMap<>();
private final Map<Integer, Integer> turns = new LinkedHashMap<>();
private final Map<Integer, String> finishes = new LinkedHashMap<>(); // game number, finish on step
private final Map<Integer, Integer> turns = new LinkedHashMap<>(); // game number, current turn
synchronized public void update(Integer taskNumber, boolean newFinish, Integer newTurn) {
Boolean oldFinish = this.finishes.getOrDefault(taskNumber, false);
synchronized public void update(Integer taskNumber, String newFinish, Integer newTurn) {
String oldFinish = this.finishes.getOrDefault(taskNumber, "");
Integer oldTurn = this.turns.getOrDefault(taskNumber, 0);
if (!this.finishes.containsKey(taskNumber)
|| !Objects.equals(oldFinish, newFinish)
@ -602,16 +606,23 @@ public class LoadTest {
}
private void updateInfo() {
// example: progress 70% [=00, +01, +01, =12, =15, =01, +61]
// example: progress 33% [=20.cd, +21, +17], AI game #9: ---
int completed = this.finishes.values().stream().mapToInt(x -> x ? 1 : 0).sum();
int completed = this.finishes.values().stream().mapToInt(x -> x.isEmpty() ? 0 : 1).sum();
int completedPercent = this.finishes.size() == 0 ? 0 : completed * 100 / this.finishes.size();
String res = this.finishes.keySet().stream()
.map(taskNumber -> String.format("%s%02d",
this.finishes.getOrDefault(taskNumber, false) ? "=" : "+",
this.turns.getOrDefault(taskNumber, 0)
))
.map(taskNumber -> {
String turn = String.format("%02d", this.turns.getOrDefault(taskNumber, 0));
String finishInfo = this.finishes.getOrDefault(taskNumber, "");
if (finishInfo.isEmpty()) {
// active
return "+" + turn;
} else {
// done
return "=" + turn + "." + finishInfo;
}
})
.collect(Collectors.joining(", "));
this.info = String.format("progress %d%% [%s]", completedPercent, res);
}
@ -875,6 +886,12 @@ public class LoadTest {
return finalGameView == null ? 0 : this.finalGameView.getTurn();
}
public String getTurnInfo() {
int turn = finalGameView == null ? 0 : this.finalGameView.getTurn();
String stepInfo = finalGameView == null ? "??" : this.finalGameView.getStep().getStepShortText().toLowerCase(Locale.ENGLISH);
return String.format("%02d.%s", turn, stepInfo);
}
public int getDurationMs() {
return finalGameView == null ? 0 : ((int) ((this.timeEnded.getTime() - this.timeStarted.getTime())));
}
@ -931,7 +948,7 @@ public class LoadTest {
String.valueOf(gameResult.randomSeed), // "random sid",
String.valueOf(gameResult.getTotalErrorsCount()), // "errors",
String.valueOf(gameResult.getTotalEffectsCount()), // "effects",
String.valueOf(gameResult.getTurn()), //"turn",
gameResult.getTurnInfo(), //"turn",
String.valueOf(gameResult.getLife1()), //"life p1",
String.valueOf(gameResult.getLife2()), //"life p2",
String.valueOf(gameResult.getCreaturesCount1()), //"creatures p1",