From 537c326789945ed604bdff8f4b9e242e92107ca8 Mon Sep 17 00:00:00 2001 From: magenoxx Date: Mon, 30 Apr 2012 18:56:36 +0400 Subject: [PATCH] [load] loading testing: added simple test for starting game by two players --- .../java/mage/client/table/TablesPanel.java | 10 +- Mage.Common/src/mage/remote/SessionImpl.java | 2 +- .../java/mage/player/ai/utils/RateCard.java | 9 +- .../main/java/mage/server/MageServerImpl.java | 2 +- .../mage/test/load/LoadCallbackClient.java | 19 ++ .../java/org/mage/test/load/LoadTest.java | 196 ++++++++++++++++++ .../org/mage/test/load/SimpleMageClient.java | 64 ++++++ .../src/test/resources/log4j.properties | 2 +- Mage/src/mage/Constants.java | 2 +- Mage/src/mage/game/combat/Combat.java | 2 +- 10 files changed, 294 insertions(+), 14 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/load/LoadCallbackClient.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/load/SimpleMageClient.java diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index 956be78d1b8..04d48638a11 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -36,6 +36,7 @@ package mage.client.table; import mage.Constants.MultiplayerAttackOption; import mage.Constants.RangeOfInfluence; +import mage.cards.decks.importer.DeckImporterUtil; import mage.client.MageFrame; import mage.client.chat.ChatPanel; import mage.client.components.MageComponents; @@ -43,10 +44,12 @@ import mage.client.dialog.JoinTableDialog; import mage.client.dialog.NewTableDialog; import mage.client.dialog.NewTournamentDialog; import mage.client.dialog.TableWaitingDialog; +import mage.client.util.ButtonColumn; +import mage.client.util.gui.GuiDisplayUtil; +import mage.game.match.MatchOptions; import mage.remote.MageRemoteException; import mage.remote.Session; -import mage.client.util.ButtonColumn; -import mage.game.match.MatchOptions; +import mage.view.MatchView; import mage.view.TableView; import org.apache.log4j.Logger; @@ -61,9 +64,6 @@ import java.util.*; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; -import mage.cards.decks.importer.DeckImporterUtil; -import mage.client.util.gui.GuiDisplayUtil; -import mage.view.MatchView; /** diff --git a/Mage.Common/src/mage/remote/SessionImpl.java b/Mage.Common/src/mage/remote/SessionImpl.java index 7e807865f64..30e8ebed5e0 100644 --- a/Mage.Common/src/mage/remote/SessionImpl.java +++ b/Mage.Common/src/mage/remote/SessionImpl.java @@ -272,7 +272,7 @@ public class SessionImpl implements Session { class CallbackHandler implements InvokerCallbackHandler { @Override public void handleCallback(Callback callback) throws HandleCallbackException { - logger.info("callback handler"); + //logger.info("callback handler"); client.processCallback((ClientCallback)callback.getCallbackObject()); } } diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java index 404f4eaa204..e3dbeb9c92c 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java @@ -1,7 +1,5 @@ package mage.player.ai.utils; -import java.io.InputStream; -import java.util.*; import mage.Constants; import mage.abilities.Ability; import mage.abilities.effects.Effect; @@ -12,6 +10,9 @@ import mage.target.common.TargetCreatureOrPlayer; import mage.target.common.TargetCreaturePermanent; import org.apache.log4j.Logger; +import java.io.InputStream; +import java.util.*; + /** * Class responsible for reading ratings from resources and rating gived cards. * Based on card relative ratings from resources and card parameters. @@ -76,7 +77,7 @@ public class RateCard { for (Ability ability : card.getAbilities()) { for (Effect effect : ability.getEffects()) { if (effect.getOutcome().equals(Constants.Outcome.Removal)) { - log.info("Found removal: " + card.getName()); + log.debug("Found removal: " + card.getName()); return 1; } if (effect.getOutcome().equals(Constants.Outcome.Damage)) { @@ -85,7 +86,7 @@ public class RateCard { if (damageEffect.getAmount() > 1) { for (Target target : ability.getTargets()) { if (target instanceof TargetCreaturePermanent || target instanceof TargetCreatureOrPlayer) { - log.info("Found damage dealer: " + card.getName()); + log.debug("Found damage dealer: " + card.getName()); return 1; } } diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index f5acdcacc72..f1283001eb7 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -264,7 +264,7 @@ public class MageServerImpl implements MageServer { execute("startMatch", sessionId, new Action() { public void execute() { UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId(); - TableManager.getInstance().startMatch(userId, roomId, tableId); + TableManager.getInstance().startMatch(userId, roomId, tableId); } }); } diff --git a/Mage.Tests/src/test/java/org/mage/test/load/LoadCallbackClient.java b/Mage.Tests/src/test/java/org/mage/test/load/LoadCallbackClient.java new file mode 100644 index 00000000000..e5d8ce871ca --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/load/LoadCallbackClient.java @@ -0,0 +1,19 @@ +package org.mage.test.load; + +import mage.interfaces.callback.CallbackClient; +import mage.interfaces.callback.ClientCallback; +import org.apache.log4j.Logger; + +/** + * @author noxx + */ +public class LoadCallbackClient implements CallbackClient { + + private static final transient Logger log = Logger.getLogger(LoadCallbackClient.class); + + @Override + public void processCallback(ClientCallback callback) { + //TODO + log.info(callback.getMethod()); + } +} 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 new file mode 100644 index 00000000000..1a12d6dfeee --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java @@ -0,0 +1,196 @@ +package org.mage.test.load; + +import mage.Constants; +import mage.cards.Card; +import mage.cards.ExpansionSet; +import mage.cards.decks.Deck; +import mage.cards.decks.DeckCardLists; +import mage.game.match.MatchOptions; +import mage.player.ai.ComputerPlayer; +import mage.remote.Connection; +import mage.remote.Session; +import mage.remote.SessionImpl; +import mage.sets.Sets; +import mage.view.GameTypeView; +import mage.view.TableView; +import org.apache.log4j.Logger; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * Intended to test Mage server under different load patterns. + * + * These tests do use server started separately, so Mage server should be started before running them. + * In case you want to debug these tests, use -Ddebug.mage that would disable client-server request timeout. + * + * Then it's also better to use -Xms256M -Xmx512M JVM options for these stests. + * + * @author noxx + */ +public class LoadTest { + + /** + * Logger for tests + */ + private static final Logger log = Logger.getLogger(LoadTest.class); + + /** + * First player's username + */ + private static final String TEST_USER_NAME = "player"; + + /** + * Second player's username + */ + private static final String TEST_USER_NAME_2 = "opponent"; + + /** + * Server connection setting. + */ + private static final String TEST_SERVER = "localhost"; + + /** + * Server connection setting. + */ + private static final int TEST_PORT = 17171; + + /** + * Server connection setting. + */ + private static final String TEST_PROXY_TYPE = "None"; + + /** + * Determines how many times test will be executed in a row. + */ + private static final int EXECUTION_COUNT = 100; + + /** + * Tests connecting with two players, creating game and starting it. + * + * Executes the test EXECUTION_COUNT times. + * + * @throws Exception + */ + @Test + public void testStartGame() throws Exception { + DeckCardLists deckList = createDeck(); + + for (int i = 0; i < EXECUTION_COUNT; i++) { + Connection connection = createConnection(TEST_USER_NAME + i); + + SimpleMageClient mageClient = new SimpleMageClient(); + Session session = new SessionImpl(mageClient); + + session.connect(connection); + UUID roomId = session.getMainRoomId(); + + GameTypeView gameTypeView = session.getGameTypes().get(0); + log.info("Game type view: " + gameTypeView.getName()); + MatchOptions options = createGameOptions(gameTypeView, session); + + TableView table = session.createTable(roomId, options); + + if (!session.joinTable(roomId, table.getTableId(), TEST_USER_NAME + i, "Human", 1, deckList)) { + log.error("Error while joining table"); + Assert.assertTrue("Error while joining table", false); + return; + } + + /*** Connect with a second player ***/ + Connection connection2 = createConnection(TEST_USER_NAME_2 + i); + SimpleMageClient mageClient2 = new SimpleMageClient(); + Session session2 = new SessionImpl(mageClient2); + session2.connect(connection2); + UUID roomId2 = session2.getMainRoomId(); + + // connect to the table with the same deck + if (!session2.joinTable(roomId2, table.getTableId(), TEST_USER_NAME_2 + i, "Human", 1, deckList)) { + log.error("Error while joining table"); + Assert.assertTrue("Error while joining table", false); + return; + } + + /*** Start game ***/ + session.startGame(roomId, table.getTableId()); + + Thread.sleep(100); + } + } + + /** + * Creates connection to the server. + * Server should run independently. + * + * @param username + * @return + */ + private Connection createConnection(String username) { + Connection connection = new Connection(); + connection.setUsername(username); + connection.setHost(TEST_SERVER); + connection.setPort(TEST_PORT); + Connection.ProxyType proxyType = Connection.ProxyType.valueByText(TEST_PROXY_TYPE); + connection.setProxyType(proxyType); + return connection; + } + + /** + * Returns random deck. + * Converts deck returned by {@link #generateRandomDeck} method to {@link DeckCardLists} format. + * + * @return + */ + private DeckCardLists createDeck() { + DeckCardLists deckList = new DeckCardLists(); + Deck deck = generateRandomDeck(); + for (Card card : deck.getCards()) { + ExpansionSet set = Sets.findSet(card.getExpansionSetCode()); + String cardName = set.findCardName(card.getCardNumber()); + deckList.getCards().add(cardName); + } + return deckList; + } + + /** + * Creates game options with two human players. + * + * @param gameTypeView + * @param session + * @return + */ + private MatchOptions createGameOptions(GameTypeView gameTypeView, Session session) { + MatchOptions options = new MatchOptions("Test game", gameTypeView.getName()); + + options.getPlayerTypes().add("Human"); + options.getPlayerTypes().add("Human"); + + options.setDeckType(session.getDeckTypes()[0]); + options.setLimited(false); + options.setAttackOption(Constants.MultiplayerAttackOption.MULTIPLE); + options.setRange(Constants.RangeOfInfluence.ALL); + options.setWinsNeeded(1); + return options; + } + + /** + * Generates random deck in {@link Deck} format. + * Uses {B}{R} as deck colors. + * + * @return + */ + private Deck generateRandomDeck() { + String selectedColors = "BR"; + List allowedColors = new ArrayList(); + log.info("Building deck with colors: " + selectedColors); + for (int i = 0; i < selectedColors.length(); i++) { + char c = selectedColors.charAt(i); + allowedColors.add(Constants.ColoredManaSymbol.lookup(c)); + } + List cardPool = Sets.generateRandomCardPool(45, allowedColors); + return ComputerPlayer.buildDeck(cardPool, allowedColors); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/load/SimpleMageClient.java b/Mage.Tests/src/test/java/org/mage/test/load/SimpleMageClient.java new file mode 100644 index 00000000000..e665168c451 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/load/SimpleMageClient.java @@ -0,0 +1,64 @@ +package org.mage.test.load; + +import mage.interfaces.MageClient; +import mage.interfaces.callback.CallbackClient; +import mage.interfaces.callback.ClientCallback; +import mage.utils.MageVersion; +import org.apache.log4j.Logger; + +import java.util.UUID; + +/** + * For tests only + * + * @author noxx + */ +public class SimpleMageClient implements MageClient { + + private UUID clientId; + private final static MageVersion version = new MageVersion(0, 8, 4, ""); + + private static final transient Logger log = Logger.getLogger(SimpleMageClient.class); + + private static CallbackClient callbackClient; + + public SimpleMageClient() { + clientId = UUID.randomUUID(); + callbackClient = new LoadCallbackClient(); + } + + @Override + public UUID getId() { + return clientId; + } + + @Override + public MageVersion getVersion() { + return version; + } + + @Override + public void connected(String message) { + // do nothing + } + + @Override + public void disconnected() { + // do nothing + } + + @Override + public void showMessage(String message) { + log.info(message); + } + + @Override + public void showError(String message) { + log.error(message); + } + + @Override + public void processCallback(ClientCallback callback) { + callbackClient.processCallback(callback); + } +} diff --git a/Mage.Tests/src/test/resources/log4j.properties b/Mage.Tests/src/test/resources/log4j.properties index 605efa2a5eb..2778ab5c228 100644 --- a/Mage.Tests/src/test/resources/log4j.properties +++ b/Mage.Tests/src/test/resources/log4j.properties @@ -5,7 +5,7 @@ log4j.rootLogger=debug, console, file, watchdog log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%-5p [%d{yyyy-MM-dd HH:mm [ss:SSS]}] %C{1}[%t]: %m%n -log4j.appender.console.Threshold=DEBUG +log4j.appender.console.Threshold=INFO #file log log4j.appender.file=org.apache.log4j.FileAppender diff --git a/Mage/src/mage/Constants.java b/Mage/src/mage/Constants.java index 62311b949f4..4891e19c8b2 100644 --- a/Mage/src/mage/Constants.java +++ b/Mage/src/mage/Constants.java @@ -401,7 +401,7 @@ public final class Constants { } public enum MultiplayerAttackOption { - MULITPLE("Attack Multiple Players"), + MULTIPLE("Attack Multiple Players"), LEFT("Attack Left"), RIGHT("Attack Right"); diff --git a/Mage/src/mage/game/combat/Combat.java b/Mage/src/mage/game/combat/Combat.java index c105716e74f..9b87de9276c 100644 --- a/Mage/src/mage/game/combat/Combat.java +++ b/Mage/src/mage/game/combat/Combat.java @@ -236,7 +236,7 @@ public class Combat implements Serializable, Copyable { } } break; - case MULITPLE: + case MULTIPLE: for (UUID opponentId : game.getOpponents(attackerId)) { addDefender(opponentId, game); }