diff --git a/rust/sea_battle_backend/src/data/game_rules.rs b/rust/sea_battle_backend/src/data/game_rules.rs index f62245d..c90d6be 100644 --- a/rust/sea_battle_backend/src/data/game_rules.rs +++ b/rust/sea_battle_backend/src/data/game_rules.rs @@ -53,6 +53,11 @@ impl GameRules { self } + pub fn with_strike_timeout(mut self, timeout: u64) -> Self { + self.strike_timeout = Some(timeout); + self + } + /// Set the list of boats for this configuration pub fn set_boats_list(&mut self, boats: &[usize]) { self.boats_str = boats diff --git a/rust/sea_battle_backend/src/test/bot_client.rs b/rust/sea_battle_backend/src/test/bot_client.rs index 2c286b0..9b2f8bd 100644 --- a/rust/sea_battle_backend/src/test/bot_client.rs +++ b/rust/sea_battle_backend/src/test/bot_client.rs @@ -39,7 +39,7 @@ pub struct BotClient { requested_rules: GameRules, layout: Option, number_plays: usize, - server_msg_callback: Option>, + server_msg_callback: Option>, play_as_bot_type: BotType, } @@ -81,7 +81,7 @@ impl BotClient { pub fn with_server_msg_callback(mut self, cb: F) -> Self where - F: FnMut(&ServerMessage) + 'static, + F: FnMut(&mut ServerMessage) + 'static, { self.server_msg_callback = Some(Box::new(cb)); self @@ -152,7 +152,7 @@ impl BotClient { }; while let Some(chunk) = socket.next().await { - let message = match chunk? { + let mut message = match chunk? { Message::Text(message) => { log::trace!("TEXT message from server: {}", message); @@ -182,7 +182,7 @@ impl BotClient { }; if let Some(cb) = &mut self.server_msg_callback { - (cb)(&message) + (cb)(&mut message) } match message { diff --git a/rust/sea_battle_backend/src/test/bot_linear_play.rs b/rust/sea_battle_backend/src/test/bot_linear_play.rs index 99b0cc0..5984d97 100644 --- a/rust/sea_battle_backend/src/test/bot_linear_play.rs +++ b/rust/sea_battle_backend/src/test/bot_linear_play.rs @@ -9,7 +9,7 @@ use crate::test::play_utils::check_no_replay_on_hit; use crate::test::{bot_client, TestPort}; use crate::utils::network_utils::wait_for_port; -fn check_strikes_are_linear(msg: &ServerMessage) { +fn check_strikes_are_linear(msg: &mut ServerMessage) { if let ServerMessage::RequestFire { status } = msg { let mut in_fire_location = true; for y in 0..status.rules.map_height { diff --git a/rust/sea_battle_backend/src/test/bot_random_play.rs b/rust/sea_battle_backend/src/test/bot_random_play.rs index 6acf5d2..03beaab 100644 --- a/rust/sea_battle_backend/src/test/bot_random_play.rs +++ b/rust/sea_battle_backend/src/test/bot_random_play.rs @@ -1,7 +1,9 @@ use tokio::task; use crate::args::Args; +use crate::consts::MIN_STRIKE_TIMEOUT; use crate::data::{BoatsLayout, GameRules}; +use crate::human_player_ws::ServerMessage; use crate::server::start_server; use crate::test::bot_client; use crate::test::bot_client::ClientEndResult; @@ -201,3 +203,32 @@ async fn full_game_no_replay_on_hit() { }) .await; } + +#[tokio::test] +async fn check_fire_time_out() { + let _ = env_logger::builder().is_test(true).try_init(); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + task::spawn_local(start_server(Args::for_test(TestPort::RandomCheckTimeout))); + wait_for_port(TestPort::RandomCheckTimeout.port()).await; + + let mut did_skip_one = false; + let res = bot_client::BotClient::new(TestPort::RandomCheckTimeout.as_url()) + .with_rules( + GameRules::random_players_rules().with_strike_timeout(MIN_STRIKE_TIMEOUT), + ) + .with_server_msg_callback(move |msg| { + if matches!(msg, ServerMessage::RequestFire { .. }) && !did_skip_one { + *msg = ServerMessage::OpponentReplacedByBot; + did_skip_one = true; + } + }) + .run_client() + .await + .unwrap(); + assert!(matches!(res, ClientEndResult::Finished { .. })); + }) + .await; +} diff --git a/rust/sea_battle_backend/src/test/mod.rs b/rust/sea_battle_backend/src/test/mod.rs index f89c97b..4edf87d 100644 --- a/rust/sea_battle_backend/src/test/mod.rs +++ b/rust/sea_battle_backend/src/test/mod.rs @@ -10,6 +10,7 @@ enum TestPort { RandomBotInvalidBoatsLayoutLenOfABoat, RandomBotFullGameMultipleRematch, RandomBotNoReplayOnHit, + RandomCheckTimeout, LinearBotFullGame, LinearBotNoReplayOnHit, IntermediateBotFullGame, diff --git a/rust/sea_battle_backend/src/test/play_utils.rs b/rust/sea_battle_backend/src/test/play_utils.rs index 7ccdc7e..b2aa791 100644 --- a/rust/sea_battle_backend/src/test/play_utils.rs +++ b/rust/sea_battle_backend/src/test/play_utils.rs @@ -1,7 +1,7 @@ use crate::human_player_ws::ServerMessage; /// Make sure player can not replay after successful hit -pub fn check_no_replay_on_hit(msg: &ServerMessage) { +pub fn check_no_replay_on_hit(msg: &mut ServerMessage) { if let ServerMessage::OpponentMustFire { status } | ServerMessage::RequestFire { status } = msg { let diff =