tests: improved load tests (better logs)

This commit is contained in:
Oleg Agafonov 2025-02-04 14:23:15 +04:00
parent b29a969fdb
commit 690bc36023
4 changed files with 17 additions and 7 deletions

View file

@ -1004,7 +1004,15 @@ public class MageServerImpl implements MageServer {
if (ex.getMessage() != null && !ex.getMessage().equals("No message")) { if (ex.getMessage() != null && !ex.getMessage().equals("No message")) {
throw new MageException("Server error: " + ex.getMessage()); throw new MageException("Server error: " + ex.getMessage());
} }
logger.error("unknown error", ex); // TODO: on logs spamming (e.g. connection problems) move it inside condition block above
if (ex instanceof ConcurrentModificationException) {
// how-to fix: game objects must be accessible by game thread only, all other threads must work with copies
logger.error("wrong threads sync error", ex);
} else {
// TODO: on logs spamming (e.g. connection problems) move it inside condition block above
logger.error("unknown error", ex);
}
} }
@Override @Override

View file

@ -42,6 +42,8 @@ public class GameSessionWatcher {
if (!killed) { if (!killed) {
Optional<User> user = userManager.getUser(userId); Optional<User> user = userManager.getUser(userId);
if (user.isPresent()) { if (user.isPresent()) {
// TODO: can be called outside of the game thread, e.g. user start watching already running game
// possible fix: getGameView must use last cached value in non game thread call (split by sessions)
user.get().fireCallback(new ClientCallback(ClientCallbackMethod.GAME_INIT, game.getId(), getGameView())); user.get().fireCallback(new ClientCallback(ClientCallbackMethod.GAME_INIT, game.getId(), getGameView()));
return true; return true;
} }

View file

@ -34,7 +34,7 @@ public class LoadCallbackClient implements CallbackClient {
private final String logsPrefix; 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 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.cd, +21, +17], AI game #9: --- private String globalProgress = ""; // example: progress 33% [20.cd, 21.__, 17.__], AI game #09: ---
public LoadCallbackClient(boolean joinGameChat, String logsPrefix, Boolean showLogsAsHtml) { public LoadCallbackClient(boolean joinGameChat, String logsPrefix, Boolean showLogsAsHtml) {
this.joinGameChat = joinGameChat; this.joinGameChat = joinGameChat;

View file

@ -51,7 +51,7 @@ public class LoadTest {
private static final Boolean TEST_SHOW_GAME_LOGS_AS_HTML = false; // html is original format with full data, but can be too bloated private static final Boolean TEST_SHOW_GAME_LOGS_AS_HTML = false; // html is original format with full data, but can be too bloated
private static final String TEST_AI_GAME_MODE = "Freeform Commander Free For All"; private static final String TEST_AI_GAME_MODE = "Freeform Commander Free For All";
private static final String TEST_AI_DECK_TYPE = "Variant Magic - Freeform Commander"; private static final String TEST_AI_DECK_TYPE = "Variant Magic - Freeform Commander";
private static final String TEST_AI_RANDOM_DECK_SETS = "LCI,LCC,WHO"; // set for random generated decks (empty for all sets usage, PELP for lands only - communication test) private static final String TEST_AI_RANDOM_DECK_SETS = "DFT,DRC"; // set for random generated decks (empty for all sets usage, PELP for lands only - communication test)
private static final String TEST_AI_RANDOM_DECK_COLORS_FOR_EMPTY_GAME = "GR"; // colors list for deck generation, empty for all colors private static final String TEST_AI_RANDOM_DECK_COLORS_FOR_EMPTY_GAME = "GR"; // colors list for deck generation, empty for all colors
private static final String TEST_AI_RANDOM_DECK_COLORS_FOR_AI_GAME = "WUBRG"; private static final String TEST_AI_RANDOM_DECK_COLORS_FOR_AI_GAME = "WUBRG";
private static final String TEST_AI_CUSTOM_DECK_PATH_1 = ""; // custom deck file instead random for player 1 (empty for random) private static final String TEST_AI_CUSTOM_DECK_PATH_1 = ""; // custom deck file instead random for player 1 (empty for random)
@ -369,7 +369,7 @@ public class LoadTest {
long randomSeed = seedsList.get(i); long randomSeed = seedsList.get(i);
logger.info("Game " + (i + 1) + " of " + seedsList.size() + ", RANDOM seed: " + randomSeed); logger.info("Game " + (i + 1) + " of " + seedsList.size() + ", RANDOM seed: " + randomSeed);
Future gameTask = executerService.submit(() -> { Future gameTask = executerService.submit(() -> {
String gameName = "AI game #" + (gameIndex + 1); String gameName = String.format("AI game #%02d", gameIndex + 1);
LoadTestGameResult gameResult = gameResults.createGame(gameIndex + 1, gameName, randomSeed); LoadTestGameResult gameResult = gameResults.createGame(gameIndex + 1, gameName, randomSeed);
playTwoAIGame(gameName, gameIndex + 1, tasksProgress, randomSeed, TEST_AI_RANDOM_DECK_COLORS_FOR_AI_GAME, TEST_AI_RANDOM_DECK_SETS, gameResult); playTwoAIGame(gameName, gameIndex + 1, tasksProgress, randomSeed, TEST_AI_RANDOM_DECK_COLORS_FOR_AI_GAME, TEST_AI_RANDOM_DECK_SETS, gameResult);
}); });
@ -606,7 +606,7 @@ public class LoadTest {
} }
private void updateInfo() { private void updateInfo() {
// example: progress 33% [=20.cd, +21, +17], AI game #9: --- // example: progress 33% [20.cd, 21.__, 17.__], AI game #09: ---
int completed = this.finishes.values().stream().mapToInt(x -> x.isEmpty() ? 0 : 1).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(); int completedPercent = this.finishes.size() == 0 ? 0 : completed * 100 / this.finishes.size();
@ -617,10 +617,10 @@ public class LoadTest {
String finishInfo = this.finishes.getOrDefault(taskNumber, ""); String finishInfo = this.finishes.getOrDefault(taskNumber, "");
if (finishInfo.isEmpty()) { if (finishInfo.isEmpty()) {
// active // active
return "+" + turn; return turn + ".__";
} else { } else {
// done // done
return "=" + turn + "." + finishInfo; return turn + "." + finishInfo;
} }
}) })
.collect(Collectors.joining(", ")); .collect(Collectors.joining(", "));