diff --git a/crates/projection-irc/tests/lib.rs b/crates/projection-irc/tests/lib.rs index 11131f2..56e9420 100644 --- a/crates/projection-irc/tests/lib.rs +++ b/crates/projection-irc/tests/lib.rs @@ -1,14 +1,14 @@ use std::time::Duration; -use anyhow::Result; +use anyhow::{anyhow, Result}; use prometheus::Registry as MetricsRegistry; -use tokio::io::{AsyncWriteExt, BufReader}; +use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader}; use tokio::net::tcp::{ReadHalf, WriteHalf}; use tokio::net::TcpStream; use lavina_core::repo::{Storage, StorageConfig}; use lavina_core::{player::PlayerRegistry, room::RoomRegistry}; -use projection_irc::{launch, read_irc_message, ServerConfig}; +use projection_irc::{launch, read_irc_message, RunningServer, ServerConfig}; struct TestScope<'a> { reader: BufReader>, @@ -44,29 +44,66 @@ impl<'a> TestScope<'a> { self.buffer.clear(); Ok(()) } + + async fn expect_eof(&mut self) -> Result<()> { + let mut buf = [0; 1]; + let len = tokio::time::timeout(self.timeout, self.reader.read(&mut buf)).await??; + if len != 0 { + return Err(anyhow!("not a eof")); + } + Ok(()) + } + + async fn expect_nothing(&mut self) -> Result<()> { + let mut buf = [0; 1]; + match tokio::time::timeout(self.timeout, self.reader.read(&mut buf)).await { + Ok(res) => Err(anyhow!("received something: {:?}", res)), + Err(_) => Ok(()), + } + } +} + +struct TestServer { + metrics: MetricsRegistry, + storage: Storage, + rooms: RoomRegistry, + players: PlayerRegistry, + server: RunningServer, +} +impl TestServer { + async fn start() -> Result { + let config = ServerConfig { + listen_on: "127.0.0.1:0".parse().unwrap(), + server_name: "testserver".into(), + }; + let mut metrics = MetricsRegistry::new(); + let mut storage = Storage::open(StorageConfig { + db_path: ":memory:".into(), + }) + .await?; + let rooms = RoomRegistry::new(&mut metrics, storage.clone()).unwrap(); + let players = PlayerRegistry::empty(rooms.clone(), &mut metrics).unwrap(); + let server = launch(config, players.clone(), rooms.clone(), metrics.clone(), storage.clone()).await.unwrap(); + Ok(TestServer { + metrics, + storage, + rooms, + players, + server, + }) + } } #[tokio::test] async fn scenario_basic() -> Result<()> { - let config = ServerConfig { - listen_on: "127.0.0.1:0".parse().unwrap(), - server_name: "testserver".into(), - }; - let mut metrics = MetricsRegistry::new(); - let mut storage = Storage::open(StorageConfig { - db_path: ":memory:".into(), - }) - .await?; - let rooms = RoomRegistry::new(&mut metrics, storage.clone()).unwrap(); - let players = PlayerRegistry::empty(rooms.clone(), &mut metrics).unwrap(); - let server = launch(config, players, rooms, metrics, storage.clone()).await.unwrap(); + let mut server = TestServer::start().await?; // test scenario - storage.create_user("tester").await?; - storage.set_password("tester", "password").await?; + server.storage.create_user("tester").await?; + server.storage.set_password("tester", "password").await?; - let mut stream = TcpStream::connect(server.addr).await?; + let mut stream = TcpStream::connect(server.server.addr).await?; let mut s = TestScope::new(&mut stream); s.send("PASS password").await?; @@ -78,11 +115,15 @@ async fn scenario_basic() -> Result<()> { s.expect(":testserver 003 tester :Welcome to Kek Server").await?; s.expect(":testserver 004 tester testserver kek-0.1.alpha.3 r CFILPQbcefgijklmnopqrstvz").await?; s.expect(":testserver 005 tester CHANTYPES=# :are supported by this server").await?; + s.expect_nothing().await?; + s.send("QUIT :Leaving").await?; + s.expect(":testserver ERROR :Leaving the server").await?; + s.expect_eof().await?; stream.shutdown().await?; // wrap up - server.terminate().await.unwrap(); + server.server.terminate().await?; Ok(()) }