2010-11-14 01:10:24 +00:00
/* PokerTH automated tests.
Copyright (C) 2010 Lothar May
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package pokerth_test ;
import java.net.Socket ;
2010-11-14 12:52:53 +00:00
import java.sql.ResultSet ;
import java.sql.Statement ;
import static org.junit.Assert.* ;
2010-11-14 01:10:24 +00:00
import java.util.ArrayList ;
import java.util.Collection ;
2011-03-08 22:49:48 +00:00
import java.util.Iterator ;
2010-11-14 01:10:24 +00:00
import org.junit.Test ;
import pokerth_protocol.* ;
import pokerth_protocol.NetGameInfo.EndRaiseModeEnumType ;
import pokerth_protocol.NetGameInfo.NetGameTypeEnumType ;
2010-11-14 12:52:53 +00:00
import pokerth_protocol.MyActionRequestMessage.MyActionRequestMessageSequenceType ;
2010-11-14 01:10:24 +00:00
import pokerth_protocol.StartEventAckMessage.StartEventAckMessageSequenceType ;
public class RunRankingGameTest extends TestBase {
@Test
public void testRunRankingGame () throws Exception {
2010-11-14 12:52:53 +00:00
Statement dbStatement = dbConn . createStatement ();
ResultSet countBeforeResult = dbStatement . executeQuery ( "SELECT COUNT(idgame) FROM game" );
countBeforeResult . first ();
long countBefore = countBeforeResult . getLong ( 1 );
2010-11-14 01:10:24 +00:00
long firstPlayerId = userInit ();
2011-02-13 18:48:46 +00:00
// Waiting for player list update.
PokerTHMessage msg ;
msg = receiveMessage ();
if ( ! msg . isPlayerListMessageSelected ()) {
failOnErrorMessage ( msg );
fail ( "Invalid message." );
}
2011-07-17 14:16:13 +00:00
Collection < InitialNonZeroAmountOfMoney > l = new ArrayList < InitialNonZeroAmountOfMoney > ();
2010-11-14 15:49:16 +00:00
String gameName = AuthUser + " run ranking game" ;
2010-11-14 12:52:53 +00:00
NetGameInfo gameInfo = createGameInfo ( 5 , EndRaiseModeEnumType . EnumType . doubleBlinds , 0 , 50 , gameName , l , 10 , 0 , 11 , 10000 );
2010-11-14 01:10:24 +00:00
sendMessage ( createGameRequestMsg (
gameInfo ,
NetGameTypeEnumType . EnumType . rankingGame ,
5 ,
7 ,
2011-02-06 15:00:36 +00:00
"" ,
false ));
2010-11-14 01:10:24 +00:00
// Game list update (new game)
msg = receiveMessage ();
if ( ! msg . isGameListMessageSelected ()) {
failOnErrorMessage ( msg );
fail ( "Invalid message." );
}
// Join game ack.
msg = receiveMessage ();
if ( msg . isJoinGameReplyMessageSelected ()) {
if ( ! msg . getJoinGameReplyMessage (). getValue (). getJoinGameResult (). isJoinGameAckSelected ()) {
fail ( "Could not create game!" );
}
}
else {
failOnErrorMessage ( msg );
fail ( "Invalid message." );
}
long gameId = msg . getJoinGameReplyMessage (). getValue (). getGameId (). getValue ();
// Game list update (player joined).
msg = receiveMessage ();
if ( ! msg . isGameListMessageSelected ()) {
failOnErrorMessage ( msg );
fail ( "Invalid message." );
}
// Let 9 additional clients join.
Socket s [] = new Socket [ 9 ] ;
long playerId [] = new long [ 9 ] ;
for ( int i = 0 ; i < 9 ; i ++ ) {
2011-01-29 16:35:04 +00:00
s [ i ] = new Socket ( "localhost" , 7234 );
2010-11-14 01:10:24 +00:00
String username = "test" + ( i + 1 );
String password = username ;
playerId [ i ] = userInit ( s [ i ] , username , password );
2011-02-13 18:48:46 +00:00
// Waiting for player list update.
do {
msg = receiveMessage ( s [ i ] );
} while ( msg . isGameListMessageSelected () || msg . isGamePlayerMessageSelected ());
if ( ! msg . isPlayerListMessageSelected ()) {
failOnErrorMessage ( msg );
fail ( "Invalid message." );
}
2011-02-06 15:00:36 +00:00
sendMessage ( joinGameRequestMsg ( gameId , "" , false ), s [ i ] );
2010-11-14 01:10:24 +00:00
do {
msg = receiveMessage ( s [ i ] );
failOnErrorMessage ( msg );
} while ( ! msg . isJoinGameReplyMessageSelected ());
if ( ! msg . getJoinGameReplyMessage (). getValue (). getJoinGameResult (). isJoinGameAckSelected ()) {
fail ( "User " + username + " could not join ranking game." );
}
// The player should have joined the game.
msg = receiveMessage ();
if ( ! msg . isPlayerListMessageSelected ()) {
failOnErrorMessage ( msg );
fail ( "Invalid message." );
}
msg = receiveMessage ();
if ( ! msg . isGamePlayerMessageSelected ()) {
failOnErrorMessage ( msg );
fail ( "Invalid message." );
}
msg = receiveMessage ();
if ( ! msg . isGameListMessageSelected ()) {
failOnErrorMessage ( msg );
fail ( "Invalid message." );
}
}
// Server should automatically send start event.
msg = receiveMessage ();
if ( ! msg . isStartEventMessageSelected ()) {
failOnErrorMessage ( msg );
fail ( "Invalid message." );
}
for ( int i = 0 ; i < 9 ; i ++ ) {
do {
msg = receiveMessage ( s [ i ] );
failOnErrorMessage ( msg );
} while ( ! msg . isStartEventMessageSelected ());
}
// Acknowledge start event.
StartEventAckMessageSequenceType startType = new StartEventAckMessageSequenceType ();
startType . setGameId ( new NonZeroId ( gameId ));
StartEventAckMessage startAck = new StartEventAckMessage ();
startAck . setValue ( startType );
msg = new PokerTHMessage ();
msg . selectStartEventAckMessage ( startAck );
sendMessage ( msg );
for ( int i = 0 ; i < 9 ; i ++ ) {
sendMessage ( msg , s [ i ] );
}
// Game list update (game now running).
msg = receiveMessage ();
if ( ! msg . isGameListMessageSelected ()) {
failOnErrorMessage ( msg );
fail ( "Invalid message." );
}
msg = receiveMessage ();
if ( ! msg . isGameStartMessageSelected ()) {
failOnErrorMessage ( msg );
fail ( "Invalid message." );
}
long handNum = 0 ;
2011-03-08 22:49:48 +00:00
long lastPlayerMoney = 0 ;
2010-11-14 01:10:24 +00:00
do {
msg = receiveMessage ();
failOnErrorMessage ( msg );
if ( msg . isHandStartMessageSelected ()) {
handNum ++ ;
2011-03-10 16:37:27 +00:00
// Cards should be encrypted for registered users.
assertTrue ( msg . getHandStartMessage (). getValue (). getYourCards (). isEncryptedCardsSelected ());
byte [] encData = msg . getHandStartMessage (). getValue (). getYourCards (). getEncryptedCards (). getCardData ();
byte [] cardData = decryptCards ( AuthPassword , encData );
int size = cardData . length ;
while ( size > 0 && cardData [ size - 1 ] == 0 ) {
size -- ;
}
String cardStr = new String ( cardData , 0 , size );
String [] cardTok = cardStr . split ( "\\s" );
// First token is player id.
assertEquals ( String . valueOf ( firstPlayerId ), cardTok [ 0 ] );
// Second token is game id.
assertEquals ( String . valueOf ( gameId ), cardTok [ 1 ] );
// Third token is hand num.
assertEquals ( String . valueOf ( handNum ), cardTok [ 2 ] );
// Fourth and fifth tokens are cards.
int card1 = Integer . valueOf ( cardTok [ 3 ] );
int card2 = Integer . valueOf ( cardTok [ 4 ] );
assertTrue ( card1 < 52 );
assertTrue ( card1 >= 0 );
assertTrue ( card2 < 52 );
assertTrue ( card2 >= 0 );
2010-11-14 01:10:24 +00:00
}
else if ( msg . isPlayersTurnMessageSelected ()) {
if ( msg . getPlayersTurnMessage (). getValue (). getPlayerId (). getValue () == firstPlayerId ) {
NetPlayerAction action = new NetPlayerAction ();
action . setValue ( NetPlayerAction . EnumType . actionAllIn );
MyActionRequestMessageSequenceType myRequest = new MyActionRequestMessageSequenceType ();
myRequest . setGameId ( new NonZeroId ( gameId ));
myRequest . setGameState ( msg . getPlayersTurnMessage (). getValue (). getGameState ());
myRequest . setHandNum ( new NonZeroId ( handNum ));
myRequest . setMyAction ( action );
2011-07-17 14:16:13 +00:00
myRequest . setMyRelativeBet ( new AmountOfMoney ( 0 ));
2010-11-14 01:10:24 +00:00
MyActionRequestMessage myAction = new MyActionRequestMessage ();
myAction . setValue ( myRequest );
PokerTHMessage outMsg = new PokerTHMessage ();
outMsg . selectMyActionRequestMessage ( myAction );
sendMessage ( outMsg );
}
}
for ( int i = 0 ; i < 9 ; i ++ ) {
while ( s [ i ] . getInputStream (). available () > 0 ) {
PokerTHMessage inMsg = receiveMessage ( s [ i ] );
failOnErrorMessage ( inMsg );
if ( inMsg . isPlayersTurnMessageSelected ()) {
if ( inMsg . getPlayersTurnMessage (). getValue (). getPlayerId (). getValue () == playerId [ i ] ) {
NetPlayerAction action = new NetPlayerAction ();
action . setValue ( NetPlayerAction . EnumType . actionFold );
MyActionRequestMessageSequenceType myRequest = new MyActionRequestMessageSequenceType ();
myRequest . setGameId ( new NonZeroId ( gameId ));
myRequest . setGameState ( inMsg . getPlayersTurnMessage (). getValue (). getGameState ());
myRequest . setHandNum ( new NonZeroId ( handNum ));
myRequest . setMyAction ( action );
2011-07-17 14:16:13 +00:00
myRequest . setMyRelativeBet ( new AmountOfMoney ( 0 ));
2010-11-14 01:10:24 +00:00
MyActionRequestMessage myAction = new MyActionRequestMessage ();
myAction . setValue ( myRequest );
PokerTHMessage outMsg = new PokerTHMessage ();
outMsg . selectMyActionRequestMessage ( myAction );
sendMessage ( outMsg , s [ i ] );
}
}
2011-03-08 22:49:48 +00:00
else if ( inMsg . isEndOfHandMessageSelected ()) {
if ( inMsg . getEndOfHandMessage (). getValue (). getEndOfHandType (). isEndOfHandHideCardsSelected ()) {
2011-07-17 14:16:13 +00:00
lastPlayerMoney = inMsg . getEndOfHandMessage (). getValue (). getEndOfHandType (). getEndOfHandHideCards (). getPlayerMoney (). getValue ();
2011-03-08 22:49:48 +00:00
} else if ( inMsg . getEndOfHandMessage (). getValue (). getEndOfHandType (). isEndOfHandShowCardsSelected ()) {
Collection < PlayerResult > result = inMsg . getEndOfHandMessage (). getValue (). getEndOfHandType (). getEndOfHandShowCards (). getPlayerResults ();
assertFalse ( result . isEmpty ());
long maxPlayerMoney = 0 ;
for ( Iterator < PlayerResult > it = result . iterator (); it . hasNext (); ) {
PlayerResult r = it . next ();
2011-07-17 14:16:13 +00:00
long curMoney = r . getPlayerMoney (). getValue ();
2011-03-08 22:49:48 +00:00
if ( curMoney > maxPlayerMoney ) {
maxPlayerMoney = curMoney ;
}
}
lastPlayerMoney = maxPlayerMoney ;
}
}
2010-11-14 01:10:24 +00:00
}
}
} while ( ! msg . isEndOfGameMessageSelected ());
2010-11-14 12:52:53 +00:00
2011-02-13 00:22:03 +00:00
for ( int i = 0 ; i < 9 ; i ++ ) {
s [ i ] . close ();
}
2010-11-14 12:52:53 +00:00
Thread . sleep ( 2000 );
2011-03-08 22:49:48 +00:00
// Last player money should be sum of all money.
assertEquals ( 10000 * 10 , lastPlayerMoney );
2010-11-14 12:52:53 +00:00
// Check database entry for the game.
ResultSet countAfterResult = dbStatement . executeQuery ( "SELECT COUNT(idgame) FROM game" );
countAfterResult . first ();
long countAfter = countAfterResult . getLong ( 1 );
assertEquals ( countBefore + 1 , countAfter );
// Select the latest game.
ResultSet gameResult = dbStatement . executeQuery ( "SELECT idgame, name, start_time, end_time FROM game WHERE start_time = (SELECT MAX(start_time) from game)" );
gameResult . first ();
long idgame = gameResult . getLong ( 1 );
String dbGameName = gameResult . getString ( 2 );
2011-02-13 17:26:17 +00:00
assertEquals ( dbGameName , gameName );
2010-11-14 12:52:53 +00:00
java . sql . Timestamp gameStart = gameResult . getTimestamp ( 3 );
java . sql . Timestamp gameEnd = gameResult . getTimestamp ( 4 );
assertTrue ( gameEnd . after ( gameStart ));
// Do not consider daylight saving time, just calculate the raw difference.
long gameDurationMsec = gameEnd . getTime () - gameStart . getTime ();
2011-02-11 12:59:42 +00:00
assertTrue ( gameDurationMsec > 10 * 1000 ); // game duration should be larger than 10 seconds.
2010-11-14 12:52:53 +00:00
assertTrue ( gameDurationMsec < 60 * 60 * 1000 ); // game duration should be smaller than 1 hour.
// Check database entries for the players in the game.
ResultSet gamePlayerResult = dbStatement . executeQuery ( "SELECT COUNT(DISTINCT player_idplayer) FROM game_has_player WHERE game_idgame = " + idgame );
gamePlayerResult . first ();
2011-02-13 17:26:17 +00:00
assertEquals ( 10 , gamePlayerResult . getLong ( 1 ));
2010-11-14 15:49:16 +00:00
// The one who always went all in should have won!
ResultSet winnerResult = dbStatement . executeQuery (
"SELECT place FROM game_has_player LEFT JOIN player_login on (game_has_player.player_idplayer = player_login.id) WHERE game_idgame = " + idgame + " AND username = '" + AuthUser + "'" );
winnerResult . first ();
2011-02-13 17:26:17 +00:00
assertEquals ( 1 , winnerResult . getLong ( 1 ));
2010-11-14 01:10:24 +00:00
}
}