diff --git a/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java b/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java index b5eaf6da36..ffccc65157 100644 --- a/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java @@ -22,10 +22,7 @@ import org.mage.test.utils.DeckTestUtils; import java.time.Instant; import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.util.*; /** * Intended to test Mage server under different load patterns. @@ -206,7 +203,7 @@ public class LoadTest { } } - public void playTwoAIGame(String gameName, String deckColors, String deckAllowedSets) { + public void playTwoAIGame(String gameName, String deckColors, String deckAllowedSets, LoadTestGameResult gameResult) { Assert.assertFalse("need deck colors", deckColors.isEmpty()); Assert.assertFalse("need allowed sets", deckAllowedSets.isEmpty()); @@ -230,6 +227,7 @@ public class LoadTest { Assert.assertTrue(monitor.session.startMatch(monitor.roomID, tableId)); // playing until game over + gameResult.start(); boolean startToWatching = false; while (true) { GameView gameView = monitor.client.getLastGameView(); @@ -243,6 +241,7 @@ public class LoadTest { + ", " + state); if (state == TableState.FINISHED) { + gameResult.finish(gameView); break; } @@ -268,15 +267,16 @@ public class LoadTest { @Test @Ignore public void test_TwoAIPlayGame_One() { - playTwoAIGame("Single AI game", "WGUBR", TEST_AI_SETS_USAGE); + LoadTestGameResult gameResult = new LoadTestGameResult(0, "test game", 0); + playTwoAIGame("Single AI game", "WGUBR", TEST_AI_SETS_USAGE, gameResult); } @Test @Ignore public void test_TwoAIPlayGame_Multiple() { - int singleGameSID = 0; // for one game test with same deck - int gamesAmount = 1000; // multiple run of one game test + int singleGameSID = 0; // set sid for same deck games, set 0 for random decks + int gamesAmount = 10; // games per run // save random seeds for repeated results (in decks generating) List seedsList = new ArrayList<>(); @@ -290,12 +290,21 @@ public class LoadTest { } } + LoadTestGameResultsList gameResults = new LoadTestGameResultsList(); for (int i = 0; i <= seedsList.size() - 1; i++) { long randomSeed = seedsList.get(i); logger.info("Game " + (i + 1) + " of " + seedsList.size() + ", RANDOM seed: " + randomSeed); RandomUtil.setSeed(randomSeed); - playTwoAIGame("AI game #" + (i + 1), "WGUBR", TEST_AI_SETS_USAGE); + String gameName = "AI game #" + (i + 1); + LoadTestGameResult gameResult = gameResults.createGame(i + 1, gameName, randomSeed); + playTwoAIGame(gameName, "WGUBR", TEST_AI_SETS_USAGE, gameResult); } + + // results + System.out.println(); + gameResults.printResultHeader(); + gameResults.printResultData(); + gameResults.printResultTotal(); } @Test @@ -688,4 +697,125 @@ public class LoadTest { return (this.runningThread != null); } } + + private class LoadTestGameResult { + int index; + String name; + long randomSeed; + Date timeStarted; + Date timeEnded = null; + GameView finalGameView = null; + + public LoadTestGameResult(int index, String name, long randomSeed) { + this.index = index; + this.name = name; + this.randomSeed = randomSeed; + } + + public void start() { + this.timeStarted = new Date(); + } + + public void finish(GameView finalGameView) { + this.timeEnded = new Date(); + this.finalGameView = finalGameView; + } + + public int getLife1() { + return this.finalGameView.getPlayers().get(0).getLife(); + } + + public int getLife2() { + return this.finalGameView.getPlayers().get(1).getLife(); + } + + public int getTurn() { + return this.finalGameView.getTurn(); + } + + public int getDuration() { + return (int) ((this.timeEnded.getTime() - this.timeStarted.getTime()) / 1000); + } + } + + private class LoadTestGameResultsList extends HashMap { + + private static final String tableFormatHeader = "|%-10s|%-15s|%-20s|%-10s|%-15s|%-15s|%-10s|%-20s|%n"; + private static final String tableFormatData = "|%-10s|%15s|%20s|%10s|%15s|%15s|%10s|%20s|%n"; + + public LoadTestGameResult createGame(int index, String name, long randomSeed) { + if (this.containsKey(index)) { + throw new IllegalArgumentException("Game with index " + index + " already exists"); + } + LoadTestGameResult res = new LoadTestGameResult(index, name, randomSeed); + this.put(index, res); + return res; + } + + public void printResultHeader() { + List data = Arrays.asList( + "index", + "name", + "random sid", + "turn", + "player 1", + "player 2", + "time, sec", + "time per turn, sec" + ); + System.out.printf(tableFormatHeader, data.toArray()); + } + + public void printResultData() { + this.values().forEach(this::printResultData); + } + + public void printResultData(LoadTestGameResult gameResult) { + List data = Arrays.asList( + String.valueOf(gameResult.index), //"index", + gameResult.name, //"name", + String.valueOf(gameResult.randomSeed), // "random sid", + String.valueOf(gameResult.getTurn()), //"turn", + String.valueOf(gameResult.getLife1()), //"player 1", + String.valueOf(gameResult.getLife2()), //"player 2", + String.valueOf(gameResult.getDuration()),// "time, sec", + String.valueOf(gameResult.getDuration() / gameResult.getTurn()) //"per turn, sec" + ); + System.out.printf(tableFormatData, data.toArray()); + } + + public void printResultTotal() { + List data = Arrays.asList( + "TOTAL/AVG", //"index", + String.valueOf(this.size()), //"name", + "", // "random sid", + String.valueOf(this.getAvgTurn()), // turn + String.valueOf(this.getAvgLife1()), // player 1 + String.valueOf(this.getAvgLife2()), // player 2 + String.valueOf(this.getAvgDuration()), // time, sec + String.valueOf(this.getAvgDurationPerTurn()) // time per turn, sec + ); + System.out.printf(tableFormatData, data.toArray()); + } + + private int getAvgTurn() { + return this.values().stream().mapToInt(LoadTestGameResult::getTurn).sum() / this.size(); + } + + private int getAvgLife1() { + return this.values().stream().mapToInt(LoadTestGameResult::getLife1).sum() / this.size(); + } + + private int getAvgLife2() { + return this.values().stream().mapToInt(LoadTestGameResult::getLife2).sum() / this.size(); + } + + private int getAvgDuration() { + return this.values().stream().mapToInt(LoadTestGameResult::getDuration).sum() / this.size(); + } + + private int getAvgDurationPerTurn() { + return getAvgDuration() / getAvgTurn(); + } + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 789d409597..f8bf0274a1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -1878,7 +1878,7 @@ public class TestPlayer implements Player { } if (choiceType.equals("target")) { printStart("Unused targets"); - if (targets.isEmpty()) { + if (!targets.isEmpty()) { System.out.println(String.join("\n", targets)); } printEnd();