Start to write tests
This commit is contained in:
parent
b6be982295
commit
70cb99a0a0
92
Cargo.lock
generated
92
Cargo.lock
generated
@ -349,6 +349,12 @@ dependencies = [
|
|||||||
"alloc-stdlib",
|
"alloc-stdlib",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@ -585,9 +591,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577"
|
checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1022,6 +1030,9 @@ dependencies = [
|
|||||||
"rand",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"serde_urlencoded",
|
||||||
|
"tokio",
|
||||||
|
"tokio-tungstenite",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1074,6 +1085,17 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha-1"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
@ -1151,6 +1173,26 @@ version = "0.15.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.13"
|
version = "0.3.13"
|
||||||
@ -1195,14 +1237,39 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"memchr",
|
"memchr",
|
||||||
"mio",
|
"mio",
|
||||||
|
"num_cpus",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
|
"tokio-macros",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-tungstenite"
|
||||||
|
version = "0.17.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181"
|
||||||
|
dependencies = [
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"tokio",
|
||||||
|
"tungstenite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
@ -1238,6 +1305,25 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tungstenite"
|
||||||
|
version = "0.17.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"http",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
"rand",
|
||||||
|
"sha-1",
|
||||||
|
"thiserror",
|
||||||
|
"url",
|
||||||
|
"utf-8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.15.0"
|
version = "1.15.0"
|
||||||
@ -1277,6 +1363,12 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf-8"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
|
@ -17,4 +17,10 @@ actix = "0.13.0"
|
|||||||
actix-web-actors = "4.1.0"
|
actix-web-actors = "4.1.0"
|
||||||
actix-rt = "2.7.0"
|
actix-rt = "2.7.0"
|
||||||
uuid = { version = "1.1.2", features = ["v4"] }
|
uuid = { version = "1.1.2", features = ["v4"] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
#reqwest = { version = "0.11.11", default-features = false, features = ["json", "rustls-tls"] }
|
||||||
|
tokio-tungstenite = "0.17.2"
|
||||||
|
serde_urlencoded = "0.7.1"
|
25
src/bot_client.rs
Normal file
25
src/bot_client.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
use tokio_tungstenite::tungstenite::handshake::client::Response;
|
||||||
|
use tokio_tungstenite::{MaybeTlsStream, WebSocketStream};
|
||||||
|
|
||||||
|
use crate::data::GameRules;
|
||||||
|
|
||||||
|
pub async fn run_client(server: &str, rules: &GameRules) -> Result<(), Box<dyn Error>> {
|
||||||
|
let url = format!(
|
||||||
|
"{}/play/bot?{}",
|
||||||
|
server.replace("http", "ws"),
|
||||||
|
serde_urlencoded::to_string(rules).unwrap()
|
||||||
|
);
|
||||||
|
log::debug!("Connecting to {}...", url);
|
||||||
|
let (socket, _) = match tokio_tungstenite::connect_async(url).await {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Failed to establish WebSocket connection! {:?}", e);
|
||||||
|
return Err(Box::new(e));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
pub mod args;
|
pub mod args;
|
||||||
|
#[cfg(test)]
|
||||||
|
pub mod bot_client;
|
||||||
pub mod consts;
|
pub mod consts;
|
||||||
pub mod data;
|
pub mod data;
|
||||||
pub mod game;
|
pub mod game;
|
||||||
@ -6,3 +8,5 @@ pub mod human_player;
|
|||||||
pub mod human_player_ws;
|
pub mod human_player_ws;
|
||||||
pub mod random_bot;
|
pub mod random_bot;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test;
|
||||||
|
@ -8,7 +8,5 @@ use sea_battle_backend::server::start_server;
|
|||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
||||||
|
|
||||||
let args: Args = Args::parse();
|
start_server(Args::parse()).await
|
||||||
|
|
||||||
start_server(&args).await
|
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ async fn start_bot_play(
|
|||||||
resp
|
resp
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start_server(args: &Args) -> std::io::Result<()> {
|
pub async fn start_server(args: Args) -> std::io::Result<()> {
|
||||||
let args_clone = args.clone();
|
let args_clone = args.clone();
|
||||||
|
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
|
39
src/test/client.rs
Normal file
39
src/test/client.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
use crate::args::Args;
|
||||||
|
use crate::bot_client;
|
||||||
|
use crate::data::GameRules;
|
||||||
|
use crate::server::start_server;
|
||||||
|
use crate::test::network_utils::wait_for_port;
|
||||||
|
use crate::test::TestPort;
|
||||||
|
use tokio::task;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn invalid_port() {
|
||||||
|
let _ = env_logger::builder().is_test(true).try_init();
|
||||||
|
|
||||||
|
bot_client::run_client(
|
||||||
|
&TestPort::ClientInvalidPort.as_url(),
|
||||||
|
&GameRules::random_players_rules(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn invalid_rules() {
|
||||||
|
let _ = env_logger::builder().is_test(true).try_init();
|
||||||
|
|
||||||
|
let local_set = task::LocalSet::new();
|
||||||
|
local_set
|
||||||
|
.run_until(async move {
|
||||||
|
let mut rules = GameRules::random_players_rules();
|
||||||
|
rules.map_width = 0;
|
||||||
|
|
||||||
|
task::spawn_local(start_server(Args::for_test(TestPort::ClientInvalidRules)));
|
||||||
|
wait_for_port(TestPort::ClientInvalidRules.port()).await;
|
||||||
|
|
||||||
|
bot_client::run_client(&TestPort::ClientInvalidRules.as_url(), &rules)
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
29
src/test/mod.rs
Normal file
29
src/test/mod.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use crate::args::Args;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
enum TestPort {
|
||||||
|
ClientInvalidPort = 20000,
|
||||||
|
ClientInvalidRules,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestPort {
|
||||||
|
pub fn port(&self) -> u16 {
|
||||||
|
(*self as u32) as u16
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_url(&self) -> String {
|
||||||
|
format!("http://127.0.0.1:{}", self.port())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Args {
|
||||||
|
fn for_test(port: TestPort) -> Self {
|
||||||
|
Self {
|
||||||
|
listen_address: format!("127.0.0.1:{}", port.port()),
|
||||||
|
cors: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod client;
|
||||||
|
mod network_utils;
|
25
src/test/network_utils.rs
Normal file
25
src/test/network_utils.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
use tokio::time;
|
||||||
|
|
||||||
|
/// Check whether a given port is open or not
|
||||||
|
pub async fn is_port_open(port: u16) -> bool {
|
||||||
|
match TcpStream::connect(("127.0.0.1", port)).await {
|
||||||
|
Ok(_) => true,
|
||||||
|
Err(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wait for a port to become available
|
||||||
|
pub async fn wait_for_port(port: u16) {
|
||||||
|
for _ in 0..50 {
|
||||||
|
if is_port_open(port).await {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
time::sleep(Duration::from_millis(10)).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
eprintln!("Port {} did not open in time!", port);
|
||||||
|
std::process::exit(2);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user