mirror of
https://codeberg.org/demostf/sync.git
synced 2026-06-03 16:44:07 +02:00
initial integration tests
This commit is contained in:
parent
ac43f7c548
commit
26183042e0
4 changed files with 964 additions and 11 deletions
777
Cargo.lock
generated
777
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -12,4 +12,7 @@ serde_json = "1.0.39"
|
||||||
enum_dispatch = "0.1"
|
enum_dispatch = "0.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
maplit = "1.0"
|
maplit = "1.0"
|
||||||
|
portpicker = "0.1.0"
|
||||||
|
websocket-lite = "0.3.0-alpha.6"
|
||||||
|
better-panic = "0.2.0"
|
||||||
151
src/integration_tests.rs
Normal file
151
src/integration_tests.rs
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
use crate::{spawn_local_server, SyncCommand};
|
||||||
|
use portpicker::pick_unused_port;
|
||||||
|
use std::thread::sleep;
|
||||||
|
use std::time::Duration;
|
||||||
|
use websocket_lite::{Client, ClientBuilder, Message, NetworkStream};
|
||||||
|
use ws::Sender;
|
||||||
|
|
||||||
|
const DELAY: Duration = Duration::from_millis(50);
|
||||||
|
|
||||||
|
struct TestHandle {
|
||||||
|
server_sender: Sender,
|
||||||
|
connect: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestHandle {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
better_panic::install();
|
||||||
|
|
||||||
|
let port = pick_unused_port().expect("No ports free");
|
||||||
|
|
||||||
|
let server_sender = spawn_local_server(port);
|
||||||
|
|
||||||
|
// give the server some time to start
|
||||||
|
sleep(DELAY);
|
||||||
|
|
||||||
|
TestHandle {
|
||||||
|
server_sender,
|
||||||
|
connect: format!("ws://localhost:{}", port),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_client(&self) -> Client<Box<dyn NetworkStream + Sync + Send + 'static>> {
|
||||||
|
ClientBuilder::new(&self.connect)
|
||||||
|
.unwrap()
|
||||||
|
.connect()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TestHandle {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.server_sender.shutdown().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn integration_tests() {
|
||||||
|
let test = TestHandle::new();
|
||||||
|
let mut owner = test.get_client();
|
||||||
|
let mut client = test.get_client();
|
||||||
|
|
||||||
|
send(
|
||||||
|
&mut owner,
|
||||||
|
SyncCommand::Create {
|
||||||
|
session: "foo".to_string(),
|
||||||
|
token: "bar".to_string(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
send(
|
||||||
|
&mut owner,
|
||||||
|
SyncCommand::Tick {
|
||||||
|
session: "foo".to_string(),
|
||||||
|
tick: 99,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
send(
|
||||||
|
&mut client,
|
||||||
|
SyncCommand::Join {
|
||||||
|
session: "foo".to_string(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Some(SyncCommand::Tick {
|
||||||
|
session: "foo".to_string(),
|
||||||
|
tick: 99,
|
||||||
|
}),
|
||||||
|
receive(&mut client)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Some(SyncCommand::Play {
|
||||||
|
session: "foo".to_string(),
|
||||||
|
play: false
|
||||||
|
}),
|
||||||
|
receive(&mut client)
|
||||||
|
);
|
||||||
|
|
||||||
|
send(
|
||||||
|
&mut owner,
|
||||||
|
SyncCommand::Play {
|
||||||
|
session: "foo".to_string(),
|
||||||
|
play: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Some(SyncCommand::Play {
|
||||||
|
session: "foo".to_string(),
|
||||||
|
play: true
|
||||||
|
}),
|
||||||
|
receive(&mut client)
|
||||||
|
);
|
||||||
|
|
||||||
|
// should be ignored
|
||||||
|
send(
|
||||||
|
&mut client,
|
||||||
|
SyncCommand::Tick {
|
||||||
|
session: "foo".to_string(),
|
||||||
|
tick: 5,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut client2 = test.get_client();
|
||||||
|
|
||||||
|
send(
|
||||||
|
&mut client2,
|
||||||
|
SyncCommand::Join {
|
||||||
|
session: "foo".to_string(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Some(SyncCommand::Tick {
|
||||||
|
session: "foo".to_string(),
|
||||||
|
tick: 99,
|
||||||
|
}),
|
||||||
|
receive(&mut client2)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Some(SyncCommand::Play {
|
||||||
|
session: "foo".to_string(),
|
||||||
|
play: true
|
||||||
|
}),
|
||||||
|
receive(&mut client2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send<T: std::io::Write>(client: &mut Client<T>, command: SyncCommand) {
|
||||||
|
client
|
||||||
|
.send(Message::text(&serde_json::to_string(&command).unwrap()))
|
||||||
|
.unwrap();
|
||||||
|
sleep(DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn receive<T: std::io::Read>(client: &mut Client<T>) -> Option<SyncCommand> {
|
||||||
|
client
|
||||||
|
.receive()
|
||||||
|
.unwrap()
|
||||||
|
.and_then(|message| message.as_text().map(|s| s.to_string()))
|
||||||
|
.map(|text| serde_json::from_str(&text).unwrap())
|
||||||
|
}
|
||||||
44
src/main.rs
44
src/main.rs
|
|
@ -14,7 +14,7 @@ use std::time::{Duration, Instant};
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
enum SyncCommand {
|
pub enum SyncCommand {
|
||||||
Create { session: String, token: String },
|
Create { session: String, token: String },
|
||||||
Join { session: String },
|
Join { session: String },
|
||||||
Tick { session: String, tick: u64 },
|
Tick { session: String, tick: u64 },
|
||||||
|
|
@ -182,13 +182,42 @@ impl Handler for Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used to spawn a server in integration tests
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn spawn_local_server(port: u16) -> ws::Sender {
|
||||||
|
use std::sync::mpsc::channel;
|
||||||
|
use std::thread::spawn;
|
||||||
|
use ws::WebSocket;
|
||||||
|
|
||||||
|
let listen_address = format!("localhost:{}", port);
|
||||||
|
|
||||||
|
let (tx, rx) = channel();
|
||||||
|
|
||||||
|
spawn(move || {
|
||||||
|
let sessions: Rc<RefCell<HashMap<String, Session>>> = Rc::default();
|
||||||
|
|
||||||
|
let ws = WebSocket::new(|out: ws::Sender| Server {
|
||||||
|
out: out.into(),
|
||||||
|
sessions: sessions.clone(),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
let ws = ws.bind(listen_address).unwrap();
|
||||||
|
|
||||||
|
tx.send(ws.broadcaster()).unwrap();
|
||||||
|
|
||||||
|
ws.run().unwrap();
|
||||||
|
});
|
||||||
|
|
||||||
|
rx.recv().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let port = std::env::var("PORT").unwrap_or_else(|_| "80".to_string());
|
let port = std::env::var("PORT").unwrap_or_else(|_| "80".to_string());
|
||||||
let listen_address = format!("0.0.0.0:{}", port);
|
let listen_address = format!("0.0.0.0:{}", port);
|
||||||
|
|
||||||
println!("listening on: {:?}", listen_address);
|
println!("listening on: {:?}", listen_address);
|
||||||
|
|
||||||
let sessions: Rc<RefCell<HashMap<String, Session>>> = Rc::new(RefCell::new(HashMap::new()));
|
let sessions: Rc<RefCell<HashMap<String, Session>>> = Rc::default();
|
||||||
|
|
||||||
listen(listen_address, |out| Server {
|
listen(listen_address, |out| Server {
|
||||||
out: out.into(),
|
out: out.into(),
|
||||||
|
|
@ -418,11 +447,11 @@ mod tests {
|
||||||
vec![
|
vec![
|
||||||
SyncCommand::Tick {
|
SyncCommand::Tick {
|
||||||
session: "test".into(),
|
session: "test".into(),
|
||||||
tick: 99
|
tick: 99,
|
||||||
},
|
},
|
||||||
SyncCommand::Play {
|
SyncCommand::Play {
|
||||||
session: "test".into(),
|
session: "test".into(),
|
||||||
play: true
|
play: true,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
mock.received()
|
mock.received()
|
||||||
|
|
@ -516,8 +545,8 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec![SyncCommand::Tick {
|
vec![SyncCommand::Tick {
|
||||||
session: "test".into(),
|
session: "test".into(),
|
||||||
tick: 999
|
tick: 999,
|
||||||
},],
|
}],
|
||||||
mock.received()
|
mock.received()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -569,3 +598,6 @@ mod tests {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod integration_tests;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue