diff options
Diffstat (limited to 'tests/src/smtp')
41 files changed, 536 insertions, 592 deletions
diff --git a/tests/src/smtp/config.rs b/tests/src/smtp/config.rs index bf578be4..7811d6f8 100644 --- a/tests/src/smtp/config.rs +++ b/tests/src/smtp/config.rs @@ -8,11 +8,11 @@ use std::{fs, net::IpAddr, path::PathBuf, sync::Arc, time::Duration}; use common::{ config::{ - server::{Listener, Server, ServerProtocol, Servers}, + server::{Listener, Listeners, ServerProtocol, TcpListener}, smtp::{throttle::parse_throttle, *}, }, expr::{functions::ResolveVariable, if_block::*, tokenizer::TokenMap, *}, - Core, + Server, }; use tokio::net::TcpSocket; @@ -301,13 +301,13 @@ fn parse_servers() { // Parse servers let mut config = Config::new(toml).unwrap(); - let servers = Servers::parse(&mut config).servers; + let servers = Listeners::parse(&mut config).servers; let id_generator = Arc::new(utils::snowflake::SnowflakeIdGenerator::new()); let expected_servers = vec![ - Server { + Listener { id: "smtp".to_string(), protocol: ServerProtocol::Smtp, - listeners: vec![Listener { + listeners: vec![TcpListener { socket: TcpSocket::new_v4().unwrap(), addr: "127.0.0.1:9925".parse().unwrap(), ttl: 3600.into(), @@ -319,11 +319,11 @@ fn parse_servers() { proxy_networks: vec![], span_id_gen: id_generator.clone(), }, - Server { + Listener { id: "smtps".to_string(), protocol: ServerProtocol::Smtp, listeners: vec![ - Listener { + TcpListener { socket: TcpSocket::new_v4().unwrap(), addr: "127.0.0.1:9465".parse().unwrap(), ttl: 4096.into(), @@ -331,7 +331,7 @@ fn parse_servers() { linger: None, nodelay: true, }, - Listener { + TcpListener { socket: TcpSocket::new_v4().unwrap(), addr: "127.0.0.1:9466".parse().unwrap(), ttl: 4096.into(), @@ -344,10 +344,10 @@ fn parse_servers() { proxy_networks: vec![], span_id_gen: id_generator.clone(), }, - Server { + Listener { id: "submission".to_string(), protocol: ServerProtocol::Smtp, - listeners: vec![Listener { + listeners: vec![TcpListener { socket: TcpSocket::new_v4().unwrap(), addr: "127.0.0.1:9991".parse().unwrap(), ttl: 3600.into(), @@ -416,7 +416,7 @@ async fn eval_if() { V_PRIORITY, V_MX, ]); - let core = Core::default(); + let core = Server::default(); for (key, _) in config.keys.clone() { if !key.starts_with("rule.") { @@ -466,7 +466,7 @@ async fn eval_dynvalue() { V_PRIORITY, V_MX, ]); - let core = Core::default(); + let core = Server::default(); for test_name in config .sub_keys("eval", "") diff --git a/tests/src/smtp/inbound/antispam.rs b/tests/src/smtp/inbound/antispam.rs index 1c3e5eb9..524ae137 100644 --- a/tests/src/smtp/inbound/antispam.rs +++ b/tests/src/smtp/inbound/antispam.rs @@ -17,14 +17,14 @@ use common::{ use mail_auth::{dmarc::Policy, DkimResult, DmarcResult, IprevResult, SpfResult, MX}; use sieve::runtime::Variable; use smtp::{ - core::{Inner, Session, SessionAddress}, + core::{Session, SessionAddress}, inbound::AuthResult, - scripts::ScriptResult, + scripts::{event_loop::RunScript, ScriptResult}, }; use store::Stores; use utils::config::Config; -use crate::smtp::{build_smtp, session::TestSession, TempDir}; +use crate::smtp::{session::TestSession, TempDir, TestSMTP}; const CONFIG: &str = r#" [spam.header] @@ -248,7 +248,7 @@ async fn antispam() { ); } - let core = build_smtp(core, Inner::default()); + let server = TestSMTP::from_core(core).server; // Run tests let base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) @@ -260,7 +260,7 @@ async fn antispam() { continue; }*/ println!("===== {test_name} ====="); - let script = core + let script = server .core .sieve .trusted_scripts @@ -280,7 +280,7 @@ async fn antispam() { let mut expected_headers = AHashMap::new(); // Build session - let mut session = Session::test(core.clone()); + let mut session = Session::test(server.clone()); for line in lines.by_ref() { if in_params { if line.is_empty() { @@ -413,9 +413,9 @@ async fn antispam() { } // Run script - let core_ = core.clone(); + let server_ = server.clone(); let script = script.clone(); - match core_ + match server_ .run_script("test".to_string(), script, params, 0) .await { diff --git a/tests/src/smtp/inbound/auth.rs b/tests/src/smtp/inbound/auth.rs index 037bbe7a..6a9679cb 100644 --- a/tests/src/smtp/inbound/auth.rs +++ b/tests/src/smtp/inbound/auth.rs @@ -11,13 +11,12 @@ use utils::config::Config; use crate::{ smtp::{ - build_smtp, session::{TestSession, VerifyResponse}, - TempDir, + TempDir, TestSMTP, }, AssertConfig, }; -use smtp::core::{Inner, Session, State}; +use smtp::core::{Session, State}; const CONFIG: &str = r#" [storage] @@ -81,7 +80,7 @@ async fn auth() { config.assert_no_errors(); // EHLO should not advertise plain text auth without TLS - let mut session = Session::test(build_smtp(core, Inner::default())); + let mut session = Session::test(TestSMTP::from_core(core).server); session.data.remote_ip_str = "10.0.0.1".to_string(); session.eval_session_params().await; session.stream.tls = false; diff --git a/tests/src/smtp/inbound/basic.rs b/tests/src/smtp/inbound/basic.rs index 1db73a77..62e0d978 100644 --- a/tests/src/smtp/inbound/basic.rs +++ b/tests/src/smtp/inbound/basic.rs @@ -5,11 +5,11 @@ */ use common::Core; -use smtp::core::{Inner, Session}; +use smtp::core::Session; use crate::smtp::{ - build_smtp, session::{TestSession, VerifyResponse}, + TestSMTP, }; #[tokio::test] @@ -17,7 +17,7 @@ async fn basic_commands() { // Enable logging crate::enable_logging(); - let mut session = Session::test(build_smtp(Core::default(), Inner::default())); + let mut session = Session::test(TestSMTP::from_core(Core::default()).server); // STARTTLS should be available on clear text connections session.stream.tls = false; diff --git a/tests/src/smtp/inbound/data.rs b/tests/src/smtp/inbound/data.rs index 1f6fb195..d4415bb6 100644 --- a/tests/src/smtp/inbound/data.rs +++ b/tests/src/smtp/inbound/data.rs @@ -10,14 +10,13 @@ use utils::config::Config; use crate::{ smtp::{ - build_smtp, inbound::TestMessage, session::{load_test_message, TestSession, VerifyResponse}, TempDir, TestSMTP, }, AssertConfig, }; -use smtp::core::{Inner, Session}; +use smtp::core::Session; const CONFIG: &str = r#" [storage] @@ -105,17 +104,16 @@ async fn data() { crate::enable_logging(); // Create temp dir for queue - let mut inner = Inner::default(); let tmp_dir = TempDir::new("smtp_data_test", true); let mut config = Config::new(tmp_dir.update_config(CONFIG)).unwrap(); let stores = Stores::parse_all(&mut config).await; let core = Core::parse(&mut config, stores, Default::default()).await; config.assert_no_errors(); - let mut qr = inner.init_test_queue(&core); // Test queue message builder - let core = build_smtp(core, inner); - let mut session = Session::test(core.clone()); + let test = TestSMTP::from_core(core); + let mut qr = test.queue_receiver; + let mut session = Session::test(test.server.clone()); session.data.remote_ip_str = "10.0.0.1".to_string(); session.eval_session_params().await; session.test_builder().await; @@ -197,7 +195,7 @@ async fn data() { .await; // Release quota - qr.clear_queue(&core).await; + qr.clear_queue(&test.server).await; // Only 1500 bytes are allowed in the queue to domain foobar.org session @@ -236,10 +234,9 @@ async fn data() { .await; // Make sure store is empty - qr.clear_queue(&core).await; - core.core - .storage - .data - .assert_is_empty(core.core.storage.blob.clone()) + qr.clear_queue(&test.server).await; + test.server + .store() + .assert_is_empty(test.server.blob_store().clone()) .await; } diff --git a/tests/src/smtp/inbound/dmarc.rs b/tests/src/smtp/inbound/dmarc.rs index bd57d035..951c9c66 100644 --- a/tests/src/smtp/inbound/dmarc.rs +++ b/tests/src/smtp/inbound/dmarc.rs @@ -19,12 +19,11 @@ use store::Stores; use utils::config::Config; use crate::smtp::{ - build_smtp, inbound::{sign::SIGNATURES, TestMessage, TestReportingEvent}, session::{TestSession, VerifyResponse}, TempDir, TestSMTP, }; -use smtp::core::{Inner, Session}; +use smtp::core::Session; const CONFIG: &str = r#" [storage] @@ -95,15 +94,11 @@ async fn dmarc() { // Enable logging crate::enable_logging(); - let mut inner = Inner::default(); let tmp_dir = TempDir::new("smtp_dmarc_test", true); let mut config = Config::new(tmp_dir.update_config(CONFIG.to_string() + SIGNATURES)).unwrap(); let stores = Stores::parse_all(&mut config).await; let core = Core::parse(&mut config, stores, Default::default()).await; - // Create temp dir for queue - let mut qr = inner.init_test_queue(&core); - // Add SPF, DKIM and DMARC records core.smtp.resolvers.dns.txt_add( "mx.example.com", @@ -166,12 +161,11 @@ async fn dmarc() { Instant::now() + Duration::from_secs(5), ); - // Create report channels - let mut rr = inner.init_test_report(); - // SPF must pass - let core = build_smtp(core, inner); - let mut session = Session::test(core.clone()); + let test = TestSMTP::from_core(core); + let mut rr = test.report_receiver; + let mut qr = test.queue_receiver; + let mut session = Session::test(test.server.clone()); session.data.remote_ip_str = "10.0.0.2".to_string(); session.data.remote_ip = session.data.remote_ip_str.parse().unwrap(); session.eval_session_params().await; @@ -246,7 +240,7 @@ async fn dmarc() { qr.assert_no_events(); // Unaligned DMARC should be rejected - core.core.smtp.resolvers.dns.txt_add( + test.server.core.smtp.resolvers.dns.txt_add( "test.net", Spf::parse(b"v=spf1 -all").unwrap(), Instant::now() + Duration::from_secs(5), diff --git a/tests/src/smtp/inbound/ehlo.rs b/tests/src/smtp/inbound/ehlo.rs index 48445ddd..907eb75d 100644 --- a/tests/src/smtp/inbound/ehlo.rs +++ b/tests/src/smtp/inbound/ehlo.rs @@ -9,12 +9,12 @@ use std::time::{Duration, Instant}; use common::Core; use mail_auth::{common::parse::TxtRecordParser, spf::Spf, SpfResult}; -use smtp::core::{Inner, Session}; +use smtp::core::Session; use utils::config::Config; use crate::smtp::{ - build_smtp, session::{TestSession, VerifyResponse}, + TestSMTP, }; const CONFIG: &str = r#" @@ -55,7 +55,7 @@ async fn ehlo() { ); // Reject non-FQDN domains - let mut session = Session::test(build_smtp(core, Inner::default())); + let mut session = Session::test(TestSMTP::from_core(core).server); session.data.remote_ip_str = "10.0.0.1".to_string(); session.data.remote_ip = session.data.remote_ip_str.parse().unwrap(); session.stream.tls = false; diff --git a/tests/src/smtp/inbound/limits.rs b/tests/src/smtp/inbound/limits.rs index 8f92d0eb..078df56a 100644 --- a/tests/src/smtp/inbound/limits.rs +++ b/tests/src/smtp/inbound/limits.rs @@ -9,12 +9,12 @@ use std::time::{Duration, Instant}; use common::Core; use tokio::sync::watch; -use smtp::core::{Inner, Session}; +use smtp::core::Session; use utils::config::Config; use crate::smtp::{ - build_smtp, session::{TestSession, VerifyResponse}, + TestSMTP, }; const CONFIG: &str = r#" @@ -38,7 +38,7 @@ async fn limits() { let (_tx, rx) = watch::channel(true); // Exceed max line length - let mut session = Session::test_with_shutdown(build_smtp(core, Inner::default()), rx); + let mut session = Session::test_with_shutdown(TestSMTP::from_core(core).server, rx); session.data.remote_ip_str = "10.0.0.1".to_string(); let mut buf = vec![b'A'; 2049]; session.ingest(&buf).await.unwrap(); diff --git a/tests/src/smtp/inbound/mail.rs b/tests/src/smtp/inbound/mail.rs index 9cdf96d4..485c039f 100644 --- a/tests/src/smtp/inbound/mail.rs +++ b/tests/src/smtp/inbound/mail.rs @@ -13,14 +13,13 @@ use common::Core; use mail_auth::{common::parse::TxtRecordParser, spf::Spf, IprevResult, SpfResult}; use smtp_proto::{MAIL_BY_NOTIFY, MAIL_BY_RETURN, MAIL_REQUIRETLS}; -use smtp::core::{Inner, Session}; +use smtp::core::Session; use store::Stores; use utils::config::Config; use crate::smtp::{ - build_smtp, session::{TestSession, VerifyResponse}, - TempDir, + TempDir, TestSMTP, }; const CONFIG: &str = r#" @@ -108,7 +107,7 @@ async fn mail() { // Be rude and do not say EHLO let core = Arc::new(core); - let mut session = Session::test(build_smtp(core.clone(), Inner::default())); + let mut session = Session::test(TestSMTP::from_core(core.clone()).server); session.data.remote_ip_str = "10.0.0.1".to_string(); session.data.remote_ip = session.data.remote_ip_str.parse().unwrap(); session.eval_session_params().await; diff --git a/tests/src/smtp/inbound/milter.rs b/tests/src/smtp/inbound/milter.rs index ccbac2f5..ed21df7e 100644 --- a/tests/src/smtp/inbound/milter.rs +++ b/tests/src/smtp/inbound/milter.rs @@ -20,7 +20,7 @@ use mail_auth::AuthenticatedMessage; use mail_parser::MessageParser; use serde::Deserialize; use smtp::{ - core::{Inner, Session, SessionData}, + core::{Session, SessionData}, inbound::{ hooks::{self, Request, SmtpResponse}, milter::{ @@ -38,7 +38,6 @@ use tokio::{ use utils::config::Config; use crate::smtp::{ - build_smtp, inbound::TestMessage, session::{load_test_message, TestSession, VerifyResponse}, TempDir, TestSMTP, @@ -108,11 +107,11 @@ async fn milter_session() { let core = Core::parse(&mut config, stores, Default::default()).await; let _rx = spawn_mock_milter_server(); tokio::time::sleep(Duration::from_millis(100)).await; - let mut inner = Inner::default(); - let mut qr = inner.init_test_queue(&core); // Build session - let mut session = Session::test(build_smtp(core, inner)); + let test = TestSMTP::from_core(core); + let mut qr = test.queue_receiver; + let mut session = Session::test(test.server); session.data.remote_ip_str = "10.0.0.1".to_string(); session.eval_session_params().await; session.ehlo("mx.doe.org").await; @@ -241,11 +240,11 @@ async fn mta_hook_session() { let core = Core::parse(&mut config, stores, Default::default()).await; let _rx = spawn_mock_mta_hook_server(); tokio::time::sleep(Duration::from_millis(100)).await; - let mut inner = Inner::default(); - let mut qr = inner.init_test_queue(&core); // Build session - let mut session = Session::test(build_smtp(core, inner)); + let test = TestSMTP::from_core(core); + let mut qr = test.queue_receiver; + let mut session = Session::test(test.server); session.data.remote_ip_str = "10.0.0.1".to_string(); session.eval_session_params().await; session.ehlo("mx.doe.org").await; diff --git a/tests/src/smtp/inbound/mod.rs b/tests/src/smtp/inbound/mod.rs index 26b9e0e0..d55bbbba 100644 --- a/tests/src/smtp/inbound/mod.rs +++ b/tests/src/smtp/inbound/mod.rs @@ -6,17 +6,17 @@ use std::time::Duration; +use common::{ + ipc::{DmarcEvent, OnHold, QueueEvent, QueueEventLock, ReportingEvent, TlsEvent}, + Server, +}; use store::{ - write::{key::DeserializeBigEndian, Bincode, QueueClass, QueueEvent, ReportEvent, ValueClass}, + write::{key::DeserializeBigEndian, Bincode, QueueClass, ReportEvent, ValueClass}, Deserialize, IterateParams, ValueKey, U64_LEN, }; use tokio::sync::mpsc::error::TryRecvError; -use smtp::{ - core::SMTP, - queue::{self, spool::QueueEventLock, DeliveryAttempt, Message, OnHold, QueueId}, - reporting::{self, DmarcEvent, TlsEvent}, -}; +use smtp::queue::{DeliveryAttempt, Message, QueueId}; use super::{QueueReceiver, ReportReceiver}; @@ -37,7 +37,7 @@ pub mod throttle; pub mod vrfy; impl QueueReceiver { - pub async fn read_event(&mut self) -> queue::Event { + pub async fn read_event(&mut self) -> QueueEvent { match tokio::time::timeout(Duration::from_millis(100), self.queue_rx.recv()).await { Ok(Some(event)) => event, Ok(None) => panic!("Channel closed."), @@ -45,7 +45,7 @@ impl QueueReceiver { } } - pub async fn try_read_event(&mut self) -> Option<queue::Event> { + pub async fn try_read_event(&mut self) -> Option<QueueEvent> { match tokio::time::timeout(Duration::from_millis(100), self.queue_rx.recv()).await { Ok(Some(event)) => Some(event), Ok(None) => panic!("Channel closed."), @@ -120,12 +120,12 @@ impl QueueReceiver { self.last_queued_message().await } - pub async fn consume_message(&mut self, core: &SMTP) -> Message { + pub async fn consume_message(&mut self, server: &Server) -> Message { self.read_event().await.assert_reload(); let message = self.last_queued_message().await; message .clone() - .remove(core, self.last_queued_due().await) + .remove(server, self.last_queued_due().await) .await; message } @@ -144,23 +144,27 @@ impl QueueReceiver { }) } - pub async fn read_queued_events(&self) -> Vec<QueueEvent> { + pub async fn read_queued_events(&self) -> Vec<store::write::QueueEvent> { let mut events = Vec::new(); - let from_key = ValueKey::from(ValueClass::Queue(QueueClass::MessageEvent(QueueEvent { - due: 0, - queue_id: 0, - }))); - let to_key = ValueKey::from(ValueClass::Queue(QueueClass::MessageEvent(QueueEvent { - due: u64::MAX, - queue_id: u64::MAX, - }))); + let from_key = ValueKey::from(ValueClass::Queue(QueueClass::MessageEvent( + store::write::QueueEvent { + due: 0, + queue_id: 0, + }, + ))); + let to_key = ValueKey::from(ValueClass::Queue(QueueClass::MessageEvent( + store::write::QueueEvent { + due: u64::MAX, + queue_id: u64::MAX, + }, + ))); self.store .iterate( IterateParams::new(from_key, to_key).ascending().no_values(), |key, _| { - events.push(QueueEvent { + events.push(store::write::QueueEvent { due: key.deserialize_be_u64(0)?, queue_id: key.deserialize_be_u64(U64_LEN)?, }); @@ -261,16 +265,16 @@ impl QueueReceiver { .expect("No event found in queue for message") } - pub async fn clear_queue(&self, core: &SMTP) { + pub async fn clear_queue(&self, server: &Server) { for message in self.read_queued_messages().await { let due = self.message_due(message.queue_id).await; - message.remove(core, due).await; + message.remove(server, due).await; } } } impl ReportReceiver { - pub async fn read_report(&mut self) -> reporting::Event { + pub async fn read_report(&mut self) -> ReportingEvent { match tokio::time::timeout(Duration::from_millis(100), self.report_rx.recv()).await { Ok(Some(event)) => event, Ok(None) => panic!("Channel closed."), @@ -278,7 +282,7 @@ impl ReportReceiver { } } - pub async fn try_read_report(&mut self) -> Option<reporting::Event> { + pub async fn try_read_report(&mut self) -> Option<ReportingEvent> { match tokio::time::timeout(Duration::from_millis(100), self.report_rx.recv()).await { Ok(Some(event)) => Some(event), Ok(None) => panic!("Channel closed."), @@ -299,17 +303,17 @@ pub trait TestQueueEvent { fn unwrap_on_hold(self) -> OnHold<QueueEventLock>; } -impl TestQueueEvent for queue::Event { +impl TestQueueEvent for QueueEvent { fn assert_reload(self) { match self { - queue::Event::Reload => (), + QueueEvent::Reload => (), e => panic!("Unexpected event: {e:?}"), } } fn unwrap_on_hold(self) -> OnHold<QueueEventLock> { match self { - queue::Event::OnHold(value) => value, + QueueEvent::OnHold(value) => value, e => panic!("Unexpected event: {e:?}"), } } @@ -320,17 +324,17 @@ pub trait TestReportingEvent { fn unwrap_tls(self) -> Box<TlsEvent>; } -impl TestReportingEvent for reporting::Event { +impl TestReportingEvent for ReportingEvent { fn unwrap_dmarc(self) -> Box<DmarcEvent> { match self { - reporting::Event::Dmarc(event) => event, + ReportingEvent::Dmarc(event) => event, e => panic!("Unexpected event: {e:?}"), } } fn unwrap_tls(self) -> Box<TlsEvent> { match self { - reporting::Event::Tls(event) => event, + ReportingEvent::Tls(event) => event, e => panic!("Unexpected event: {e:?}"), } } diff --git a/tests/src/smtp/inbound/rcpt.rs b/tests/src/smtp/inbound/rcpt.rs index 6eea2ff1..2f972174 100644 --- a/tests/src/smtp/inbound/rcpt.rs +++ b/tests/src/smtp/inbound/rcpt.rs @@ -12,12 +12,11 @@ use smtp_proto::{RCPT_NOTIFY_DELAY, RCPT_NOTIFY_FAILURE, RCPT_NOTIFY_SUCCESS}; use store::Stores; use utils::config::Config; -use smtp::core::{Inner, Session, State}; +use smtp::core::{Session, State}; use crate::smtp::{ - build_smtp, session::{TestSession, VerifyResponse}, - TempDir, + TempDir, TestSMTP, }; const CONFIG: &str = r#" @@ -94,7 +93,7 @@ async fn rcpt() { let core = Core::parse(&mut config, stores, Default::default()).await; // RCPT without MAIL FROM - let mut session = Session::test(build_smtp(core, Inner::default())); + let mut session = Session::test(TestSMTP::from_core(core).server); session.data.remote_ip_str = "10.0.0.1".to_string(); session.eval_session_params().await; session.ehlo("mx1.foobar.org").await; diff --git a/tests/src/smtp/inbound/rewrite.rs b/tests/src/smtp/inbound/rewrite.rs index 3ea7fe3d..4b17d70e 100644 --- a/tests/src/smtp/inbound/rewrite.rs +++ b/tests/src/smtp/inbound/rewrite.rs @@ -6,10 +6,10 @@ use common::Core; -use smtp::core::{Inner, Session}; +use smtp::core::Session; use utils::config::Config; -use crate::smtp::{build_smtp, session::TestSession}; +use crate::smtp::{session::TestSession, TestSMTP}; const CONFIG: &str = r#" [session.mail] @@ -74,7 +74,7 @@ async fn address_rewrite() { let core = Core::parse(&mut config, Default::default(), Default::default()).await; // Init session - let mut session = Session::test(build_smtp(core, Inner::default())); + let mut session = Session::test(TestSMTP::from_core(core).server); session.data.remote_ip_str = "10.0.0.1".to_string(); session.eval_session_params().await; session.ehlo("mx.doe.org").await; diff --git a/tests/src/smtp/inbound/scripts.rs b/tests/src/smtp/inbound/scripts.rs index 144fc908..4833aad9 100644 --- a/tests/src/smtp/inbound/scripts.rs +++ b/tests/src/smtp/inbound/scripts.rs @@ -10,7 +10,6 @@ use std::{fmt::Write, fs, path::PathBuf}; use crate::{ enable_logging, smtp::{ - build_smtp, inbound::{sign::SIGNATURES, TestMessage, TestQueueEvent}, session::{TestSession, VerifyResponse}, TempDir, TestSMTP, @@ -20,8 +19,8 @@ use crate::{ use common::Core; use smtp::{ - core::{Inner, Session}, - scripts::ScriptResult, + core::Session, + scripts::{event_loop::RunScript, ScriptResult}, }; use store::Stores; use utils::config::Config; @@ -135,7 +134,7 @@ async fn sieve_scripts() { } // Prepare config - let mut inner = Inner::default(); + let tmp_dir = TempDir::new("smtp_sieve_test", true); let mut config = Config::new( tmp_dir.update_config( @@ -155,18 +154,18 @@ async fn sieve_scripts() { config.resolve_all_macros().await; let stores = Stores::parse_all(&mut config).await; let core = Core::parse(&mut config, stores, Default::default()).await; - let mut qr = inner.init_test_queue(&core); config.assert_no_errors(); // Build session - let core = build_smtp(core, inner); - let mut session = Session::test(core.clone()); + let test = TestSMTP::from_core(core); + let mut qr = test.queue_receiver; + let mut session = Session::test(test.server.clone()); session.data.remote_ip_str = "10.0.0.88".parse().unwrap(); session.data.remote_ip = session.data.remote_ip_str.parse().unwrap(); assert!(!session.init_conn().await); // Run tests - for (name, script) in &core.core.sieve.trusted_scripts { + for (name, script) in &test.server.core.sieve.trusted_scripts { if name.starts_with("stage_") || name.ends_with("_include") { continue; } @@ -174,10 +173,13 @@ async fn sieve_scripts() { let params = session .build_script_parameters("data") .set_variable("from", "john.doe@example.org") - .with_envelope(&core.core, &session, 0) + .with_envelope(&test.server, &session, 0) .await; - let core_ = core.clone(); - match core_.run_script(name.to_string(), script, params, 0).await { + match test + .server + .run_script(name.to_string(), script, params, 0) + .await + { ScriptResult::Accept { .. } => (), ScriptResult::Reject(message) => panic!("{}", message), err => { @@ -248,7 +250,7 @@ async fn sieve_scripts() { ) .await; qr.assert_no_events(); - qr.clear_queue(&core).await; + qr.clear_queue(&test.server).await; // Expect message delivery plus a notification session @@ -295,7 +297,7 @@ async fn sieve_scripts() { .assert_not_contains("X-Part-Number: 5") .assert_not_contains("THIS IS A PIECE OF HTML TEXT"); qr.assert_no_events(); - qr.clear_queue(&core).await; + qr.clear_queue(&test.server).await; // Expect a modified message delivery plus a notification session @@ -332,7 +334,7 @@ async fn sieve_scripts() { .assert_contains("X-Part-Number: 5") .assert_contains("THIS IS A PIECE OF HTML TEXT") .assert_not_contains("X-My-Header: true"); - qr.clear_queue(&core).await; + qr.clear_queue(&test.server).await; // Expect a modified redirected message session diff --git a/tests/src/smtp/inbound/sign.rs b/tests/src/smtp/inbound/sign.rs index 6b2a39bb..5ccc2dae 100644 --- a/tests/src/smtp/inbound/sign.rs +++ b/tests/src/smtp/inbound/sign.rs @@ -16,12 +16,11 @@ use store::Stores; use utils::config::Config; use crate::smtp::{ - build_smtp, inbound::TestMessage, session::{TestSession, VerifyResponse}, TempDir, TestSMTP, }; -use smtp::core::{Inner, Session}; +use smtp::core::Session; pub const SIGNATURES: &str = " [signature.rsa] @@ -131,10 +130,6 @@ async fn sign_and_seal() { let mut config = Config::new(tmp_dir.update_config(CONFIG.to_string() + SIGNATURES)).unwrap(); let stores = Stores::parse_all(&mut config).await; let core = Core::parse(&mut config, stores, Default::default()).await; - let mut inner = Inner::default(); - - // Create temp dir for queue - let mut qr = inner.init_test_queue(&core); // Add SPF, DKIM and DMARC records core.smtp.resolvers.dns.txt_add( @@ -176,7 +171,9 @@ async fn sign_and_seal() { ); // Test DKIM signing - let mut session = Session::test(build_smtp(core, inner)); + let test = TestSMTP::from_core(core); + let mut qr = test.queue_receiver; + let mut session = Session::test(test.server); session.data.remote_ip_str = "10.0.0.2".to_string(); session.eval_session_params().await; session.ehlo("mx.example.com").await; diff --git a/tests/src/smtp/inbound/throttle.rs b/tests/src/smtp/inbound/throttle.rs index 7def5f38..414ec302 100644 --- a/tests/src/smtp/inbound/throttle.rs +++ b/tests/src/smtp/inbound/throttle.rs @@ -6,9 +6,9 @@ use std::time::Duration; -use crate::smtp::{build_smtp, session::TestSession, TempDir}; +use crate::smtp::{session::TestSession, TempDir, TestSMTP}; use common::Core; -use smtp::core::{Inner, Session, SessionAddress}; +use smtp::core::{Session, SessionAddress}; use store::Stores; use utils::config::Config; @@ -51,10 +51,9 @@ async fn throttle_inbound() { let mut config = Config::new(tmp_dir.update_config(CONFIG)).unwrap(); let stores = Stores::parse_all(&mut config).await; let core = Core::parse(&mut config, stores, Default::default()).await; - let inner = Inner::default(); // Test connection concurrency limit - let mut session = Session::test(build_smtp(core, inner)); + let mut session = Session::test(TestSMTP::from_core(core).server); session.data.remote_ip_str = "10.0.0.1".to_string(); assert!( session.is_allowed().await, diff --git a/tests/src/smtp/inbound/vrfy.rs b/tests/src/smtp/inbound/vrfy.rs index f431d503..9345dad1 100644 --- a/tests/src/smtp/inbound/vrfy.rs +++ b/tests/src/smtp/inbound/vrfy.rs @@ -9,13 +9,12 @@ use common::Core; use store::Stores; use utils::config::Config; -use smtp::core::{Inner, Session}; +use smtp::core::Session; use crate::{ smtp::{ - build_smtp, session::{TestSession, VerifyResponse}, - TempDir, + TempDir, TestSMTP, }, AssertConfig, }; @@ -79,7 +78,7 @@ async fn vrfy_expn() { config.assert_no_errors(); // EHLO should not advertise VRFY/EXPN to 10.0.0.2 - let mut session = Session::test(build_smtp(core, Inner::default())); + let mut session = Session::test(TestSMTP::from_core(core).server); session.data.remote_ip_str = "10.0.0.2".to_string(); session.eval_session_params().await; session diff --git a/tests/src/smtp/lookup/sql.rs b/tests/src/smtp/lookup/sql.rs index b20ce71a..a6582597 100644 --- a/tests/src/smtp/lookup/sql.rs +++ b/tests/src/smtp/lookup/sql.rs @@ -18,15 +18,11 @@ use utils::config::Config; use crate::{ directory::DirectoryStore, smtp::{ - build_smtp, session::{TestSession, VerifyResponse}, - TempDir, + TempDir, TestSMTP, }, }; -use smtp::{ - core::{Inner, Session}, - queue::RecipientDomain, -}; +use smtp::{core::Session, queue::RecipientDomain}; const CONFIG: &str = r#" [storage] @@ -106,7 +102,6 @@ async fn lookup_sql() { let mut config = Config::new(temp_dir.update_config(CONFIG)).unwrap(); let stores = Stores::parse_all(&mut config).await; - let inner = Inner::default(); let core = Core::parse(&mut config, stores, Default::default()).await; core.smtp.resolvers.dns.mx_add( @@ -123,6 +118,8 @@ async fn lookup_sql() { store: core.storage.lookups.get("sql").unwrap().clone(), }; + let test = TestSMTP::from_core(core); + // Create tables handle.create_test_directory().await; @@ -184,7 +181,8 @@ async fn lookup_sql() { let e = Expression::try_parse(&mut config, ("test", test_name, "expr"), &token_map).unwrap(); assert_eq!( - core.eval_expr::<String, _>(&e, &RecipientDomain::new("test.org"), "text", 0) + test.server + .eval_expr::<String, _>(&e, &RecipientDomain::new("test.org"), "text", 0) .await .unwrap(), config.value(("test", test_name, "expect")).unwrap(), @@ -193,7 +191,7 @@ async fn lookup_sql() { ); } - let mut session = Session::test(build_smtp(core, inner)); + let mut session = Session::test(test.server); session.data.remote_ip_str = "10.0.0.50".parse().unwrap(); session.eval_session_params().await; session.stream.tls = true; diff --git a/tests/src/smtp/lookup/utils.rs b/tests/src/smtp/lookup/utils.rs index 17bf5821..59773fcc 100644 --- a/tests/src/smtp/lookup/utils.rs +++ b/tests/src/smtp/lookup/utils.rs @@ -18,14 +18,16 @@ use mail_auth::MX; use ::smtp::outbound::NextHop; use mail_parser::DateTime; use smtp::{ - core::Inner, - outbound::{lookup::ToNextHop, mta_sts::parse::ParsePolicy}, + outbound::{ + lookup::{DnsLookup, ToNextHop}, + mta_sts::parse::ParsePolicy, + }, queue::RecipientDomain, reporting::AggregateTimestamp, }; use utils::config::Config; -use crate::smtp::build_smtp; +use crate::smtp::TestSMTP; const CONFIG_V4: &str = r#" [queue.outbound.source-ip] @@ -65,11 +67,9 @@ async fn lookup_ip() { "10.0.0.4".parse().unwrap(), ]; let mut config = Config::new(CONFIG_V4).unwrap(); - let core = build_smtp( - Core::parse(&mut config, Default::default(), Default::default()).await, - Inner::default(), - ); - core.core.smtp.resolvers.dns.ipv4_add( + let test = + TestSMTP::from_core(Core::parse(&mut config, Default::default(), Default::default()).await); + test.server.core.smtp.resolvers.dns.ipv4_add( "mx.foobar.org", vec![ "172.168.0.100".parse().unwrap(), @@ -77,14 +77,15 @@ async fn lookup_ip() { ], Instant::now() + Duration::from_secs(10), ); - core.core.smtp.resolvers.dns.ipv6_add( + test.server.core.smtp.resolvers.dns.ipv6_add( "mx.foobar.org", vec!["e:f::a".parse().unwrap(), "e:f::b".parse().unwrap()], Instant::now() + Duration::from_secs(10), ); // Ipv4 strategy - let resolve_result = core + let resolve_result = test + .server .resolve_host( &NextHop::MX("mx.foobar.org"), &RecipientDomain::new("envelope"), @@ -103,11 +104,9 @@ async fn lookup_ip() { // Ipv6 strategy let mut config = Config::new(CONFIG_V6).unwrap(); - let core = build_smtp( - Core::parse(&mut config, Default::default(), Default::default()).await, - Inner::default(), - ); - core.core.smtp.resolvers.dns.ipv4_add( + let test = + TestSMTP::from_core(Core::parse(&mut config, Default::default(), Default::default()).await); + test.server.core.smtp.resolvers.dns.ipv4_add( "mx.foobar.org", vec![ "172.168.0.100".parse().unwrap(), @@ -115,12 +114,13 @@ async fn lookup_ip() { ], Instant::now() + Duration::from_secs(10), ); - core.core.smtp.resolvers.dns.ipv6_add( + test.server.core.smtp.resolvers.dns.ipv6_add( "mx.foobar.org", vec!["e:f::a".parse().unwrap(), "e:f::b".parse().unwrap()], Instant::now() + Duration::from_secs(10), ); - let resolve_result = core + let resolve_result = test + .server .resolve_host( &NextHop::MX("mx.foobar.org"), &RecipientDomain::new("envelope"), diff --git a/tests/src/smtp/management/queue.rs b/tests/src/smtp/management/queue.rs index 181713fb..9c0a4fa8 100644 --- a/tests/src/smtp/management/queue.rs +++ b/tests/src/smtp/management/queue.rs @@ -16,7 +16,7 @@ use reqwest::{header::AUTHORIZATION, Method, StatusCode}; use crate::{ jmap::ManagementApi, - smtp::{outbound::TestServer, session::TestSession}, + smtp::{session::TestSession, TestSMTP}, }; use smtp::queue::{manager::SpawnQueue, QueueId, Status}; @@ -70,12 +70,12 @@ async fn manage_queue() { crate::enable_logging(); // Start remote test server - let mut remote = TestServer::new("smtp_manage_queue_remote", REMOTE, true).await; + let mut remote = TestSMTP::new("smtp_manage_queue_remote", REMOTE).await; let _rx = remote.start(&[ServerProtocol::Smtp]).await; let remote_core = remote.build_smtp(); // Start local management interface - let local = TestServer::new("smtp_manage_queue_local", LOCAL, true).await; + let local = TestSMTP::new("smtp_manage_queue_local", LOCAL).await; // Add mock DNS entries let core = local.build_smtp(); @@ -134,7 +134,10 @@ async fn manage_queue() { ("f", ("", vec!["success@foobar.org", "delay@foobar.org"])), ]); let mut session = local.new_session(); - local.qr.queue_rx.spawn(local.instance.clone()); + local + .queue_receiver + .queue_rx + .spawn(local.server.inner.clone()); session.data.remote_ip_str = "10.0.0.1".to_string(); session.eval_session_params().await; session.ehlo("foobar.net").await; @@ -160,7 +163,7 @@ async fn manage_queue() { tokio::time::sleep(Duration::from_millis(100)).await; assert_eq!( remote - .qr + .queue_receiver .consume_message(&remote_core) .await .recipients @@ -315,7 +318,7 @@ async fn manage_queue() { tokio::time::sleep(Duration::from_millis(100)).await; assert_eq!( remote - .qr + .queue_receiver .consume_message(&remote_core) .await .recipients diff --git a/tests/src/smtp/management/report.rs b/tests/src/smtp/management/report.rs index 76052870..28754963 100644 --- a/tests/src/smtp/management/report.rs +++ b/tests/src/smtp/management/report.rs @@ -7,7 +7,10 @@ use std::sync::Arc; use ahash::{AHashMap, HashSet}; -use common::config::{server::ServerProtocol, smtp::report::AggregateFrequency}; +use common::{ + config::{server::ServerProtocol, smtp::report::AggregateFrequency}, + ipc::{DmarcEvent, PolicyType, TlsEvent}, +}; use jmap::api::management::queue::Report; use mail_auth::{ @@ -23,9 +26,9 @@ use reqwest::Method; use crate::{ jmap::ManagementApi, - smtp::{management::queue::List, outbound::TestServer}, + smtp::{management::queue::List, TestSMTP}, }; -use smtp::reporting::{scheduler::SpawnReport, DmarcEvent, TlsEvent}; +use smtp::reporting::{scheduler::SpawnReport, SmtpReporting}; const CONFIG: &str = r#" [storage] @@ -58,10 +61,13 @@ async fn manage_reports() { crate::enable_logging(); // Start reporting service - let local = TestServer::new("smtp_manage_reports", CONFIG, true).await; + let local = TestSMTP::new("smtp_manage_reports", CONFIG).await; let _rx = local.start(&[ServerProtocol::Http]).await; let core = local.build_smtp(); - local.rr.report_rx.spawn(local.instance.clone()); + local + .report_receiver + .report_rx + .spawn(local.server.inner.clone()); // Send test reporting events core.schedule_report(DmarcEvent { @@ -98,7 +104,7 @@ async fn manage_reports() { .await; core.schedule_report(TlsEvent { domain: "foobar.org".to_string(), - policy: smtp::reporting::PolicyType::None, + policy: PolicyType::None, failure: None, tls_record: Arc::new(TlsRpt::parse(b"v=TLSRPTv1;rua=mailto:reports@foobar.org").unwrap()), interval: AggregateFrequency::Daily, @@ -106,7 +112,7 @@ async fn manage_reports() { .await; core.schedule_report(TlsEvent { domain: "foobar.net".to_string(), - policy: smtp::reporting::PolicyType::Sts(None), + policy: PolicyType::Sts(None), failure: FailureDetails::new(ResultType::StsPolicyInvalid).into(), tls_record: Arc::new(TlsRpt::parse(b"v=TLSRPTv1;rua=mailto:reports@foobar.net").unwrap()), interval: AggregateFrequency::Weekly, diff --git a/tests/src/smtp/mod.rs b/tests/src/smtp/mod.rs index 09d60a33..275c42ae 100644 --- a/tests/src/smtp/mod.rs +++ b/tests/src/smtp/mod.rs @@ -6,11 +6,21 @@ use std::{path::PathBuf, sync::Arc}; -use common::Core; - -use smtp::core::{Inner, SMTP}; -use store::{BlobStore, Store}; -use tokio::sync::mpsc; +use common::{ + config::server::{Listeners, ServerProtocol}, + ipc::{QueueEvent, ReportingEvent}, + manager::boot::build_ipc, + Core, Inner, Server, +}; + +use jmap::api::JmapSessionManager; +use session::{DummyIo, TestSession}; +use smtp::core::{Session, SmtpSessionManager}; +use store::{BlobStore, Store, Stores}; +use tokio::sync::{mpsc, watch}; +use utils::config::Config; + +use crate::AssertConfig; pub mod config; pub mod inbound; @@ -72,40 +82,148 @@ pub fn add_test_certs(config: &str) -> String { pub struct QueueReceiver { store: Store, blob_store: BlobStore, - pub queue_rx: mpsc::Receiver<smtp::queue::Event>, + pub queue_rx: mpsc::Receiver<QueueEvent>, } pub struct ReportReceiver { - pub report_rx: mpsc::Receiver<smtp::reporting::Event>, + pub report_rx: mpsc::Receiver<ReportingEvent>, } -pub trait TestSMTP { - fn init_test_queue(&mut self, core: &Core) -> QueueReceiver; - fn init_test_report(&mut self) -> ReportReceiver; +pub struct TestSMTP { + pub server: Server, + pub temp_dir: Option<TempDir>, + pub queue_receiver: QueueReceiver, + pub report_receiver: ReportReceiver, } -impl TestSMTP for Inner { - fn init_test_queue(&mut self, core: &Core) -> QueueReceiver { - let (queue_tx, queue_rx) = mpsc::channel(128); - self.queue_tx = queue_tx; +const CONFIG: &str = r#" +[session.connect] +hostname = "'mx.example.org'" +greeting = "'Test SMTP instance'" + +[server.listener.smtp-debug] +bind = ['127.0.0.1:9925'] +protocol = 'smtp' + +[server.listener.lmtp-debug] +bind = ['127.0.0.1:9924'] +protocol = 'lmtp' +tls.implicit = true + +[server.listener.management-debug] +bind = ['127.0.0.1:9980'] +protocol = 'http' +tls.implicit = true + +[server.socket] +reuse-addr = true + +[server.tls] +enable = true +implicit = false +certificate = 'default' + +[certificate.default] +cert = '%{file:{CERT}}%' +private-key = '%{file:{PK}}%' + +[storage] +data = "sqlite" +lookup = "sqlite" +blob = "sqlite" +fts = "sqlite" + +[store."sqlite"] +type = "sqlite" +path = "{TMP}/queue.db" - QueueReceiver { - blob_store: core.storage.blob.clone(), - store: core.storage.data.clone(), - queue_rx, +"#; + +impl TestSMTP { + pub fn from_core(core: impl Into<Arc<Core>>) -> Self { + Self::from_core_and_tempdir(core, None) + } + + fn from_core_and_tempdir(core: impl Into<Arc<Core>>, temp_dir: Option<TempDir>) -> Self { + let core = core.into(); + let (ipc, mut ipc_rxs) = build_ipc(); + + TestSMTP { + queue_receiver: QueueReceiver { + store: core.storage.data.clone(), + blob_store: core.storage.blob.clone(), + queue_rx: ipc_rxs.queue_rx.take().unwrap(), + }, + report_receiver: ReportReceiver { + report_rx: ipc_rxs.report_rx.take().unwrap(), + }, + server: Server { + inner: Inner { + shared_core: core.as_ref().clone().into_shared(), + data: Default::default(), + ipc, + } + .into(), + core, + }, + temp_dir, } } - fn init_test_report(&mut self) -> ReportReceiver { - let (report_tx, report_rx) = mpsc::channel(128); - self.report_tx = report_tx; - ReportReceiver { report_rx } + pub async fn new(name: &str, config: impl AsRef<str>) -> TestSMTP { + let temp_dir = TempDir::new(name, true); + let mut config = + Config::new(temp_dir.update_config(add_test_certs(CONFIG) + config.as_ref())).unwrap(); + config.resolve_all_macros().await; + let stores = Stores::parse_all(&mut config).await; + let core = Core::parse(&mut config, stores, Default::default()).await; + + Self::from_core_and_tempdir(core, Some(temp_dir)) + } + + pub async fn start(&self, protocols: &[ServerProtocol]) -> watch::Sender<bool> { + // Spawn listeners + let mut config = Config::new(CONFIG).unwrap(); + let mut servers = Listeners::parse(&mut config); + servers.parse_tcp_acceptors(&mut config, self.server.inner.clone()); + + // Filter out protocols + servers + .servers + .retain(|server| protocols.contains(&server.protocol)); + + // Start servers + servers.bind_and_drop_priv(&mut config); + config.assert_no_errors(); + + servers + .spawn(|server, acceptor, shutdown_rx| { + match &server.protocol { + ServerProtocol::Smtp | ServerProtocol::Lmtp => server.spawn( + SmtpSessionManager::new(self.server.inner.clone()), + self.server.inner.clone(), + acceptor, + shutdown_rx, + ), + ServerProtocol::Http => server.spawn( + JmapSessionManager::new(self.server.inner.clone()), + self.server.inner.clone(), + acceptor, + shutdown_rx, + ), + ServerProtocol::Imap | ServerProtocol::Pop3 | ServerProtocol::ManageSieve => { + unreachable!() + } + }; + }) + .0 + } + + pub fn new_session(&self) -> Session<DummyIo> { + Session::test(self.server.clone()) } -} -fn build_smtp(core: impl Into<Arc<Core>>, inner: impl Into<Arc<Inner>>) -> SMTP { - SMTP { - core: core.into(), - inner: inner.into(), + pub fn build_smtp(&self) -> Server { + self.server.clone() } } diff --git a/tests/src/smtp/outbound/dane.rs b/tests/src/smtp/outbound/dane.rs index 80c5242a..4bc3d853 100644 --- a/tests/src/smtp/outbound/dane.rs +++ b/tests/src/smtp/outbound/dane.rs @@ -19,6 +19,7 @@ use common::{ server::ServerProtocol, smtp::resolver::{DnsRecordCache, DnssecResolver, Resolvers, Tlsa, TlsaEntry}, }, + ipc::PolicyType, Core, }; use mail_auth::{ @@ -38,15 +39,11 @@ use rustls_pki_types::CertificateDer; use crate::smtp::{ inbound::{TestMessage, TestQueueEvent, TestReportingEvent}, - outbound::TestServer, session::{TestSession, VerifyResponse}, + TestSMTP, }; -use smtp::outbound::dane::verify::TlsaVerify; -use smtp::{ - core::SMTP, - queue::{Error, ErrorDetails, Status}, - reporting::PolicyType, -}; +use smtp::outbound::dane::{dnssec::TlsaLookup, verify::TlsaVerify}; +use smtp::queue::{Error, ErrorDetails, Status}; const LOCAL: &str = r#" [session.rcpt] @@ -85,11 +82,11 @@ async fn dane_verify() { crate::enable_logging(); // Start test server - let mut remote = TestServer::new("smtp_dane_remote", REMOTE, true).await; + let mut remote = TestSMTP::new("smtp_dane_remote", REMOTE).await; let _rx = remote.start(&[ServerProtocol::Smtp]).await; // Fail on missing TLSA record - let mut local = TestServer::new("smtp_dane_local", LOCAL, true).await; + let mut local = TestSMTP::new("smtp_dane_local", LOCAL).await; // Add mock DNS entries let core = local.build_smtp(); @@ -120,24 +117,24 @@ async fn dane_verify() { .send_message("john@test.org", &["bill@foobar.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; local - .qr + .queue_receiver .expect_message() .await - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<bill@foobar.org> (DANE failed to authenticate") .assert_contains("No TLSA records found"); - local.qr.read_event().await.assert_reload(); - local.qr.assert_no_events(); + local.queue_receiver.read_event().await.assert_reload(); + local.queue_receiver.assert_no_events(); // Expect TLS failure report - let report = local.rr.read_report().await.unwrap_tls(); + let report = local.report_receiver.read_report().await.unwrap_tls(); assert_eq!(report.domain, "foobar.org"); assert_eq!(report.policy, PolicyType::Tlsa(None)); assert_eq!( @@ -173,30 +170,30 @@ async fn dane_verify() { .send_message("john@test.org", &["bill@foobar.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; local - .qr + .queue_receiver .expect_message() .await - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<bill@foobar.org> (DANE failed to authenticate") .assert_contains("No matching certificates found"); - local.qr.read_event().await.assert_reload(); - local.qr.assert_no_events(); + local.queue_receiver.read_event().await.assert_reload(); + local.queue_receiver.assert_no_events(); // Expect TLS failure report - let report = local.rr.read_report().await.unwrap_tls(); + let report = local.report_receiver.read_report().await.unwrap_tls(); assert_eq!(report.policy, PolicyType::Tlsa(tlsa.into())); assert_eq!( report.failure.as_ref().unwrap().result_type, ResultType::ValidationFailure ); - remote.qr.assert_no_events(); + remote.queue_receiver.assert_no_events(); // DANE successful delivery let tlsa = Arc::new(Tlsa { @@ -221,23 +218,23 @@ async fn dane_verify() { .send_message("john@test.org", &["bill@foobar.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; - local.qr.read_event().await.assert_reload(); - local.qr.assert_no_events(); + local.queue_receiver.read_event().await.assert_reload(); + local.queue_receiver.assert_no_events(); remote - .qr + .queue_receiver .expect_message() .await - .read_lines(&remote.qr) + .read_lines(&remote.queue_receiver) .await .assert_contains("using TLSv1.3 with cipher"); // Expect TLS success report - let report = local.rr.read_report().await.unwrap_tls(); + let report = local.report_receiver.read_report().await.unwrap_tls(); assert_eq!(report.policy, PolicyType::Tlsa(tlsa.into())); assert!(report.failure.is_none()); } @@ -260,10 +257,7 @@ async fn dane_test() { mta_sts: LruCache::with_capacity(10), }, }; - let r = SMTP { - core: core.into(), - inner: Default::default(), - }; + let r = TestSMTP::from_core(core).build_smtp(); // Add dns entries let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); diff --git a/tests/src/smtp/outbound/extensions.rs b/tests/src/smtp/outbound/extensions.rs index 57bbb1f2..e434769c 100644 --- a/tests/src/smtp/outbound/extensions.rs +++ b/tests/src/smtp/outbound/extensions.rs @@ -12,8 +12,8 @@ use smtp_proto::{MAIL_REQUIRETLS, MAIL_RET_HDRS, MAIL_SMTPUTF8, RCPT_NOTIFY_NEVE use crate::smtp::{ inbound::{TestMessage, TestQueueEvent}, - outbound::TestServer, session::{TestSession, VerifyResponse}, + TestSMTP, }; const LOCAL: &str = r#" @@ -54,11 +54,11 @@ async fn extensions() { crate::enable_logging(); // Start test server - let mut remote = TestServer::new("smtp_ext_remote", REMOTE, true).await; + let mut remote = TestSMTP::new("smtp_ext_remote", REMOTE).await; let _rx = remote.start(&[ServerProtocol::Smtp]).await; // Successful delivery with DSN - let mut local = TestServer::new("smtp_ext_local", LOCAL, true).await; + let mut local = TestSMTP::new("smtp_ext_local", LOCAL).await; // Add mock DNS entries let core = local.build_smtp(); @@ -89,27 +89,27 @@ async fn extensions() { ) .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; local - .qr + .queue_receiver .expect_message() .await - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<bill@foobar.org> (delivered to") .assert_contains("Final-Recipient: rfc822;bill@foobar.org") .assert_contains("Action: delivered"); - local.qr.read_event().await.assert_reload(); + local.queue_receiver.read_event().await.assert_reload(); remote - .qr + .queue_receiver .expect_message() .await - .read_lines(&remote.qr) + .read_lines(&remote.queue_receiver) .await .assert_contains("using TLSv1.3 with cipher"); @@ -118,23 +118,23 @@ async fn extensions() { .send_message("john@test.org", &["bill@foobar.org"], "test:arc", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; local - .qr + .queue_receiver .expect_message() .await - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<bill@foobar.org> (host 'mx.foobar.org' rejected command 'MAIL FROM:") .assert_contains("Action: failed") .assert_contains("Diagnostic-Code: smtp;552") .assert_contains("Status: 5.3.4"); - local.qr.read_event().await.assert_reload(); - remote.qr.assert_no_events(); + local.queue_receiver.read_event().await.assert_reload(); + remote.queue_receiver.assert_no_events(); // Test DSN, SMTPUTF8 and REQUIRETLS extensions session @@ -146,13 +146,13 @@ async fn extensions() { ) .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; - local.qr.read_event().await.assert_reload(); - let message = remote.qr.expect_message().await; + local.queue_receiver.read_event().await.assert_reload(); + let message = remote.queue_receiver.expect_message().await; assert_eq!(message.env_id, Some("abc123".to_string())); assert!((message.flags & MAIL_RET_HDRS) != 0); assert!((message.flags & MAIL_REQUIRETLS) != 0); diff --git a/tests/src/smtp/outbound/fallback_relay.rs b/tests/src/smtp/outbound/fallback_relay.rs index 76173bda..7c7a8831 100644 --- a/tests/src/smtp/outbound/fallback_relay.rs +++ b/tests/src/smtp/outbound/fallback_relay.rs @@ -10,7 +10,7 @@ use common::config::server::ServerProtocol; use mail_auth::MX; use store::write::now; -use crate::smtp::{outbound::TestServer, session::TestSession}; +use crate::smtp::{session::TestSession, TestSMTP}; const LOCAL: &str = r#" [queue.outbound] @@ -55,9 +55,9 @@ async fn fallback_relay() { crate::enable_logging(); // Start test server - let mut remote = TestServer::new("smtp_fallback_remote", REMOTE, true).await; + let mut remote = TestSMTP::new("smtp_fallback_remote", REMOTE).await; let _rx = remote.start(&[ServerProtocol::Smtp]).await; - let mut local = TestServer::new("smtp_fallback_local", LOCAL, true).await; + let mut local = TestSMTP::new("smtp_fallback_local", LOCAL).await; // Add mock DNS entries let core = local.build_smtp(); @@ -88,12 +88,12 @@ async fn fallback_relay() { .send_message("john@test.org", &["bill@foobar.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; - let mut retry = local.qr.expect_message().await; + let mut retry = local.queue_receiver.expect_message().await; let prev_due = retry.domains[0].retry.due; let next_due = now(); let queue_id = retry.queue_id; @@ -102,11 +102,11 @@ async fn fallback_relay() { .save_changes(&core, prev_due.into(), next_due.into()) .await; local - .qr + .queue_receiver .delivery_attempt(queue_id) .await .try_deliver(core.clone()) .await; tokio::time::sleep(Duration::from_millis(100)).await; - remote.qr.expect_message().await; + remote.queue_receiver.expect_message().await; } diff --git a/tests/src/smtp/outbound/ip_lookup.rs b/tests/src/smtp/outbound/ip_lookup.rs index 23e4625c..d19fc2d4 100644 --- a/tests/src/smtp/outbound/ip_lookup.rs +++ b/tests/src/smtp/outbound/ip_lookup.rs @@ -9,7 +9,7 @@ use std::time::{Duration, Instant}; use common::config::server::ServerProtocol; use mail_auth::{IpLookupStrategy, MX}; -use crate::smtp::{outbound::TestServer, session::TestSession}; +use crate::smtp::{session::TestSession, TestSMTP}; const LOCAL: &str = r#" [session.rcpt] @@ -34,13 +34,13 @@ async fn ip_lookup_strategy() { crate::enable_logging(); // Start test server - let mut remote = TestServer::new("smtp_iplookup_remote", REMOTE, true).await; + let mut remote = TestSMTP::new("smtp_iplookup_remote", REMOTE).await; let _rx = remote.start(&[ServerProtocol::Smtp]).await; for strategy in [IpLookupStrategy::Ipv6Only, IpLookupStrategy::Ipv6thenIpv4] { //println!("-> Strategy: {:?}", strategy); // Add mock DNS entries - let mut local = TestServer::new("smtp_iplookup_local", LOCAL, true).await; + let mut local = TestSMTP::new("smtp_iplookup_local", LOCAL).await; let core = local.build_smtp(); core.core.smtp.resolvers.dns.mx_add( "foobar.org", @@ -72,16 +72,16 @@ async fn ip_lookup_strategy() { .send_message("john@test.org", &["bill@foobar.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; tokio::time::sleep(Duration::from_millis(100)).await; if matches!(strategy, IpLookupStrategy::Ipv6thenIpv4) { - remote.qr.expect_message().await; + remote.queue_receiver.expect_message().await; } else { - let message = local.qr.last_queued_message().await; + let message = local.queue_receiver.last_queued_message().await; let status = message.domains[0].status.to_string(); assert!( status.contains("Connection refused"), diff --git a/tests/src/smtp/outbound/lmtp.rs b/tests/src/smtp/outbound/lmtp.rs index f27c94fc..f47e40d9 100644 --- a/tests/src/smtp/outbound/lmtp.rs +++ b/tests/src/smtp/outbound/lmtp.rs @@ -8,11 +8,11 @@ use std::time::{Duration, Instant}; use crate::smtp::{ inbound::TestMessage, - outbound::TestServer, session::{TestSession, VerifyResponse}, + TestSMTP, }; -use common::config::server::ServerProtocol; -use smtp::queue::{DeliveryAttempt, Event}; +use common::{config::server::ServerProtocol, ipc::QueueEvent}; +use smtp::queue::{spool::SmtpSpool, DeliveryAttempt}; use store::write::now; const REMOTE: &str = " @@ -66,11 +66,11 @@ async fn lmtp_delivery() { crate::enable_logging(); // Start test server - let mut remote = TestServer::new("lmtp_delivery_remote", REMOTE, true).await; + let mut remote = TestSMTP::new("lmtp_delivery_remote", REMOTE).await; let _rx = remote.start(&[ServerProtocol::Lmtp]).await; // Multiple delivery attempts - let mut local = TestServer::new("lmtp_delivery_local", LOCAL, true).await; + let mut local = TestSMTP::new("lmtp_delivery_local", LOCAL).await; // Add mock DNS entries let core = local.build_smtp(); @@ -100,17 +100,17 @@ async fn lmtp_delivery() { ) .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; let mut dsn = Vec::new(); loop { - match local.qr.try_read_event().await { - Some(Event::Reload) => {} - Some(Event::OnHold(_)) => unreachable!(), - None | Some(Event::Stop) => break, + match local.queue_receiver.try_read_event().await { + Some(QueueEvent::Reload) => {} + Some(QueueEvent::OnHold(_)) => unreachable!(), + None | Some(QueueEvent::Stop) => break, } let events = core.next_event().await; @@ -133,14 +133,14 @@ async fn lmtp_delivery() { } } } - local.qr.assert_queue_is_empty().await; + local.queue_receiver.assert_queue_is_empty().await; assert_eq!(dsn.len(), 4); let mut dsn = dsn.into_iter(); dsn.next() .unwrap() - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<bill@foobar.org> (delivered to") .assert_contains("<jane@foobar.org> (delivered to") @@ -150,28 +150,28 @@ async fn lmtp_delivery() { dsn.next() .unwrap() - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<delay@foobar.org> (host 'lmtp.foobar.org' rejected") .assert_contains("Action: delayed"); dsn.next() .unwrap() - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<delay@foobar.org> (host 'lmtp.foobar.org' rejected") .assert_contains("Action: delayed"); dsn.next() .unwrap() - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<delay@foobar.org> (host 'lmtp.foobar.org' rejected") .assert_contains("Action: failed"); assert_eq!( remote - .qr + .queue_receiver .expect_message() .await .recipients @@ -184,5 +184,5 @@ async fn lmtp_delivery() { "john@foobar.org".to_string() ] ); - remote.qr.assert_no_events(); + remote.queue_receiver.assert_no_events(); } diff --git a/tests/src/smtp/outbound/mod.rs b/tests/src/smtp/outbound/mod.rs index 43334dbe..fd5900fb 100644 --- a/tests/src/smtp/outbound/mod.rs +++ b/tests/src/smtp/outbound/mod.rs @@ -4,25 +4,6 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use common::{ - config::server::{ServerProtocol, Servers}, - Core, -}; -use jmap::{api::JmapSessionManager, JMAP}; -use store::{BlobStore, Store, Stores}; -use tokio::sync::{mpsc, watch}; - -use ::smtp::core::{Inner, Session, SmtpInstance, SmtpSessionManager, SMTP}; -use utils::config::Config; - -use crate::AssertConfig; - -use super::{ - add_test_certs, - session::{DummyIo, TestSession}, - QueueReceiver, ReportReceiver, TempDir, TestSMTP, -}; - pub mod dane; pub mod extensions; pub mod fallback_relay; @@ -32,144 +13,3 @@ pub mod mta_sts; pub mod smtp; pub mod throttle; pub mod tls; - -const CONFIG: &str = r#" -[session.connect] -hostname = "'mx.example.org'" -greeting = "'Test SMTP instance'" - -[server.listener.smtp-debug] -bind = ['127.0.0.1:9925'] -protocol = 'smtp' - -[server.listener.lmtp-debug] -bind = ['127.0.0.1:9924'] -protocol = 'lmtp' -tls.implicit = true - -[server.listener.management-debug] -bind = ['127.0.0.1:9980'] -protocol = 'http' -tls.implicit = true - -[server.socket] -reuse-addr = true - -[server.tls] -enable = true -implicit = false -certificate = 'default' - -[certificate.default] -cert = '%{file:{CERT}}%' -private-key = '%{file:{PK}}%' - -[storage] -data = "sqlite" -lookup = "sqlite" -blob = "sqlite" -fts = "sqlite" - -[store."sqlite"] -type = "sqlite" -path = "{TMP}/queue.db" - -"#; - -pub struct TestServer { - pub instance: SmtpInstance, - pub temp_dir: TempDir, - pub qr: QueueReceiver, - pub rr: ReportReceiver, -} - -impl TestServer { - pub async fn new(name: &str, config: impl AsRef<str>, with_receiver: bool) -> TestServer { - let temp_dir = TempDir::new(name, true); - let mut config = - Config::new(temp_dir.update_config(add_test_certs(CONFIG) + config.as_ref())).unwrap(); - config.resolve_all_macros().await; - let stores = Stores::parse_all(&mut config).await; - let core = Core::parse(&mut config, stores, Default::default()).await; - let mut inner = Inner::default(); - let qr = if with_receiver { - inner.init_test_queue(&core) - } else { - QueueReceiver { - store: Store::default(), - blob_store: BlobStore::default(), - queue_rx: mpsc::channel(1).1, - } - }; - let rr = if with_receiver { - inner.init_test_report() - } else { - ReportReceiver { - report_rx: mpsc::channel(1).1, - } - }; - - TestServer { - instance: SmtpInstance::new(core.into_shared(), inner), - temp_dir, - qr, - rr, - } - } - - pub async fn start(&self, protocols: &[ServerProtocol]) -> watch::Sender<bool> { - // Spawn listeners - let mut config = Config::new(CONFIG).unwrap(); - let mut servers = Servers::parse(&mut config); - servers.parse_tcp_acceptors(&mut config, self.instance.core.clone()); - - // Filter out protocols - servers - .servers - .retain(|server| protocols.contains(&server.protocol)); - - // Start servers - servers.bind_and_drop_priv(&mut config); - let instance = self.instance.clone(); - let smtp_manager = SmtpSessionManager::new(instance.clone()); - let jmap = JMAP::init( - &mut config, - mpsc::channel(1).1, - instance.core.clone(), - instance.inner.clone(), - ) - .await; - let jmap_manager = JmapSessionManager::new(jmap); - config.assert_no_errors(); - - servers - .spawn(|server, acceptor, shutdown_rx| { - match &server.protocol { - ServerProtocol::Smtp | ServerProtocol::Lmtp => server.spawn( - smtp_manager.clone(), - instance.core.clone(), - acceptor, - shutdown_rx, - ), - ServerProtocol::Http => server.spawn( - jmap_manager.clone(), - instance.core.clone(), - acceptor, - shutdown_rx, - ), - ServerProtocol::Imap | ServerProtocol::Pop3 | ServerProtocol::ManageSieve => { - unreachable!() - } - }; - }) - .0 - } - - pub fn new_session(&self) -> Session<DummyIo> { - Session::test(self.build_smtp()) - } - - pub fn build_smtp(&self) -> SMTP { - SMTP::from(self.instance.clone()) - } -} diff --git a/tests/src/smtp/outbound/mta_sts.rs b/tests/src/smtp/outbound/mta_sts.rs index bae82bd7..29e8a605 100644 --- a/tests/src/smtp/outbound/mta_sts.rs +++ b/tests/src/smtp/outbound/mta_sts.rs @@ -9,7 +9,10 @@ use std::{ time::{Duration, Instant}, }; -use common::config::{server::ServerProtocol, smtp::resolver::Policy}; +use common::{ + config::{server::ServerProtocol, smtp::resolver::Policy}, + ipc::PolicyType, +}; use mail_auth::{ common::parse::TxtRecordParser, mta_sts::{MtaSts, ReportUri, TlsRpt}, @@ -19,13 +22,10 @@ use mail_auth::{ use crate::smtp::{ inbound::{TestMessage, TestQueueEvent, TestReportingEvent}, - outbound::TestServer, session::{TestSession, VerifyResponse}, + TestSMTP, }; -use smtp::{ - outbound::mta_sts::{lookup::STS_TEST_POLICY, parse::ParsePolicy}, - reporting::PolicyType, -}; +use smtp::outbound::mta_sts::{lookup::STS_TEST_POLICY, parse::ParsePolicy}; const LOCAL: &str = r#" [session.rcpt] @@ -63,11 +63,11 @@ async fn mta_sts_verify() { crate::enable_logging(); // Start test server - let mut remote = TestServer::new("smtp_mta_sts_remote", REMOTE, true).await; + let mut remote = TestSMTP::new("smtp_mta_sts_remote", REMOTE).await; let _rx = remote.start(&[ServerProtocol::Smtp]).await; // Fail on missing MTA-STS record - let mut local = TestServer::new("smtp_mta_sts_local", LOCAL, true).await; + let mut local = TestSMTP::new("smtp_mta_sts_local", LOCAL).await; // Add mock DNS entries let core = local.build_smtp(); @@ -98,23 +98,23 @@ async fn mta_sts_verify() { .send_message("john@test.org", &["bill@foobar.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; local - .qr + .queue_receiver .expect_message() .await - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<bill@foobar.org> (MTA-STS failed to authenticate") .assert_contains("Record not found"); - local.qr.read_event().await.assert_reload(); + local.queue_receiver.read_event().await.assert_reload(); // Expect TLS failure report - let report = local.rr.read_report().await.unwrap_tls(); + let report = local.report_receiver.read_report().await.unwrap_tls(); assert_eq!(report.domain, "foobar.org"); assert_eq!(report.policy, PolicyType::Sts(None)); assert_eq!( @@ -136,23 +136,23 @@ async fn mta_sts_verify() { .send_message("john@test.org", &["bill@foobar.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; local - .qr + .queue_receiver .expect_message() .await - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<bill@foobar.org> (MTA-STS failed to authenticate") .assert_contains("No 'mx' entries found"); - local.qr.read_event().await.assert_reload(); + local.queue_receiver.read_event().await.assert_reload(); // Expect TLS failure report - let report = local.rr.read_report().await.unwrap_tls(); + let report = local.report_receiver.read_report().await.unwrap_tls(); assert_eq!(report.policy, PolicyType::Sts(None)); assert_eq!( report.failure.as_ref().unwrap().result_type, @@ -171,23 +171,23 @@ async fn mta_sts_verify() { .send_message("john@test.org", &["bill@foobar.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; local - .qr + .queue_receiver .expect_message() .await - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<bill@foobar.org> (MTA-STS failed to authenticate") .assert_contains("not authorized by policy"); - local.qr.read_event().await.assert_reload(); + local.queue_receiver.read_event().await.assert_reload(); // Expect TLS failure report - let report = local.rr.read_report().await.unwrap_tls(); + let report = local.report_receiver.read_report().await.unwrap_tls(); assert_eq!( report.policy, PolicyType::Sts( @@ -202,7 +202,7 @@ async fn mta_sts_verify() { report.failure.as_ref().unwrap().result_type, ResultType::ValidationFailure ); - remote.qr.assert_no_events(); + remote.queue_receiver.assert_no_events(); // MTA-STS successful validation core.core.smtp.resolvers.dns.txt_add( @@ -222,22 +222,22 @@ async fn mta_sts_verify() { .send_message("john@test.org", &["bill@foobar.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; - local.qr.read_event().await.assert_reload(); + local.queue_receiver.read_event().await.assert_reload(); remote - .qr + .queue_receiver .expect_message() .await - .read_lines(&remote.qr) + .read_lines(&remote.queue_receiver) .await .assert_contains("using TLSv1.3 with cipher"); // Expect TLS success report - let report = local.rr.read_report().await.unwrap_tls(); + let report = local.report_receiver.read_report().await.unwrap_tls(); assert_eq!( report.policy, PolicyType::Sts( diff --git a/tests/src/smtp/outbound/smtp.rs b/tests/src/smtp/outbound/smtp.rs index f24ffb1f..13b2f7ff 100644 --- a/tests/src/smtp/outbound/smtp.rs +++ b/tests/src/smtp/outbound/smtp.rs @@ -6,16 +6,16 @@ use std::time::{Duration, Instant}; -use common::config::server::ServerProtocol; +use common::{config::server::ServerProtocol, ipc::QueueEvent}; use mail_auth::MX; use store::write::now; use crate::smtp::{ inbound::{TestMessage, TestQueueEvent}, - outbound::TestServer, session::{TestSession, VerifyResponse}, + TestSMTP, }; -use smtp::queue::{DeliveryAttempt, Event}; +use smtp::queue::{spool::SmtpSpool, DeliveryAttempt}; const LOCAL: &str = r#" [session.rcpt] @@ -74,12 +74,12 @@ async fn smtp_delivery() { crate::enable_logging(); // Start test server - let mut remote = TestServer::new("smtp_delivery_remote", REMOTE, true).await; + let mut remote = TestSMTP::new("smtp_delivery_remote", REMOTE).await; let _rx = remote.start(&[ServerProtocol::Smtp]).await; let remote_core = remote.build_smtp(); // Multiple delivery attempts - let mut local = TestServer::new("smtp_delivery_local", LOCAL, true).await; + let mut local = TestSMTP::new("smtp_delivery_local", LOCAL).await; // Add mock DNS entries let core = local.build_smtp(); @@ -124,11 +124,11 @@ async fn smtp_delivery() { "250", ) .await; - let message = local.qr.expect_message().await; + let message = local.queue_receiver.expect_message().await; let num_domains = message.domains.len(); assert_eq!(num_domains, 3); local - .qr + .queue_receiver .delivery_attempt(message.queue_id) .await .try_deliver(core.clone()) @@ -136,10 +136,10 @@ async fn smtp_delivery() { let mut dsn = Vec::new(); let mut domain_retries = vec![0; num_domains]; loop { - match local.qr.try_read_event().await { - Some(Event::Reload) => {} - Some(Event::OnHold(_)) => unreachable!(), - None | Some(Event::Stop) => break, + match local.queue_receiver.try_read_event().await { + Some(QueueEvent::Reload) => {} + Some(QueueEvent::OnHold(_)) => unreachable!(), + None | Some(QueueEvent::Stop) => break, } let events = core.next_event().await; @@ -173,14 +173,14 @@ async fn smtp_delivery() { "retries {domain_retries:?}" ); - local.qr.assert_queue_is_empty().await; + local.queue_receiver.assert_queue_is_empty().await; assert_eq!(dsn.len(), 5); let mut dsn = dsn.into_iter(); dsn.next() .unwrap() - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<ok@foobar.net> (delivered to") .assert_contains("<ok@foobar.org> (delivered to") @@ -190,7 +190,7 @@ async fn smtp_delivery() { dsn.next() .unwrap() - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<delay@foobar.net> (host ") .assert_contains("<delay@foobar.org> (host ") @@ -198,27 +198,27 @@ async fn smtp_delivery() { dsn.next() .unwrap() - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<delay@foobar.org> (host ") .assert_contains("Action: delayed"); dsn.next() .unwrap() - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<delay@foobar.org> (host "); dsn.next() .unwrap() - .read_lines(&local.qr) + .read_lines(&local.queue_receiver) .await .assert_contains("<delay@foobar.net> (host ") .assert_contains("Action: failed"); assert_eq!( remote - .qr + .queue_receiver .consume_message(&remote_core) .await .recipients @@ -229,7 +229,7 @@ async fn smtp_delivery() { ); assert_eq!( remote - .qr + .queue_receiver .consume_message(&remote_core) .await .recipients @@ -239,7 +239,7 @@ async fn smtp_delivery() { vec!["ok@foobar.net".to_string()] ); - remote.qr.assert_no_events(); + remote.queue_receiver.assert_no_events(); // SMTP smuggling for separator in ["\n", "\r"].iter() { @@ -256,18 +256,18 @@ async fn smtp_delivery() { .send_message("john@doe.org", &["bill@foobar.com"], &message, "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; - local.qr.read_event().await.assert_reload(); + local.queue_receiver.read_event().await.assert_reload(); let message = remote - .qr + .queue_receiver .consume_message(&remote_core) .await - .read_message(&remote.qr) + .read_message(&remote.queue_receiver) .await; assert!( diff --git a/tests/src/smtp/outbound/throttle.rs b/tests/src/smtp/outbound/throttle.rs index 2ea8223a..9c625a51 100644 --- a/tests/src/smtp/outbound/throttle.rs +++ b/tests/src/smtp/outbound/throttle.rs @@ -13,10 +13,9 @@ use mail_auth::MX; use store::write::now; use crate::smtp::{ - inbound::TestQueueEvent, outbound::TestServer, queue::manager::new_message, - session::TestSession, + inbound::TestQueueEvent, queue::manager::new_message, session::TestSession, TestSMTP, }; -use smtp::queue::{Domain, Message, QueueEnvelope, Schedule, Status}; +use smtp::queue::{throttle::IsAllowed, Domain, Message, QueueEnvelope, Schedule, Status}; const CONFIG: &str = r#" [session.rcpt] @@ -73,7 +72,7 @@ async fn throttle_outbound() { let mut test_message = new_message(0); test_message.return_path_domain = "foobar.org".to_string(); - let mut local = TestServer::new("smtp_throttle_outbound", CONFIG, true).await; + let mut local = TestSMTP::new("smtp_throttle_outbound", CONFIG).await; let core = local.build_smtp(); let mut session = local.new_session(); @@ -83,7 +82,10 @@ async fn throttle_outbound() { session .send_message("john@foobar.org", &["bill@test.org"], "test:no_dkim", "250") .await; - assert_eq!(local.qr.last_queued_due().await as i64 - now() as i64, 0); + assert_eq!( + local.queue_receiver.last_queued_due().await as i64 - now() as i64, + 0 + ); // Throttle sender let mut in_flight = vec![]; @@ -102,13 +104,13 @@ async fn throttle_outbound() { // Expect concurrency throttle for sender domain 'foobar.org' local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; tokio::time::sleep(Duration::from_millis(100)).await; - local.qr.read_event().await.unwrap_on_hold(); + local.queue_receiver.read_event().await.unwrap_on_hold(); in_flight.clear(); // Expect rate limit throttle for sender domain 'foobar.net' @@ -128,14 +130,14 @@ async fn throttle_outbound() { .send_message("john@foobar.net", &["bill@test.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; tokio::time::sleep(Duration::from_millis(100)).await; - local.qr.read_event().await.assert_reload(); - let due = local.qr.last_queued_due().await - now(); + local.queue_receiver.read_event().await.assert_reload(); + let due = local.queue_receiver.last_queued_due().await - now(); assert!(due > 0, "Due: {}", due); // Expect concurrency throttle for recipient domain 'example.org' @@ -167,13 +169,13 @@ async fn throttle_outbound() { ) .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; tokio::time::sleep(Duration::from_millis(100)).await; - local.qr.read_event().await.unwrap_on_hold(); + local.queue_receiver.read_event().await.unwrap_on_hold(); in_flight.clear(); // Expect rate limit throttle for recipient domain 'example.net' @@ -204,14 +206,14 @@ async fn throttle_outbound() { ) .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; tokio::time::sleep(Duration::from_millis(100)).await; - local.qr.read_event().await.assert_reload(); - let due = local.qr.last_queued_due().await - now(); + local.queue_receiver.read_event().await.assert_reload(); + let due = local.queue_receiver.last_queued_due().await - now(); assert!(due > 0, "Due: {}", due); // Expect concurrency throttle for mx 'mx.test.org' @@ -250,12 +252,12 @@ async fn throttle_outbound() { .send_message("john@test.net", &["jane@test.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; - local.qr.read_event().await.unwrap_on_hold(); + local.queue_receiver.read_event().await.unwrap_on_hold(); in_flight.clear(); // Expect rate limit throttle for mx 'mx.test.net' @@ -287,15 +289,15 @@ async fn throttle_outbound() { .send_message("john@test.net", &["jane@test.net"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; tokio::time::sleep(Duration::from_millis(100)).await; - local.qr.read_event().await.assert_reload(); - let due = local.qr.last_queued_due().await - now(); + local.queue_receiver.read_event().await.assert_reload(); + let due = local.queue_receiver.last_queued_due().await - now(); assert!(due > 0, "Due: {}", due); } diff --git a/tests/src/smtp/outbound/tls.rs b/tests/src/smtp/outbound/tls.rs index 32c712ce..105c7f3e 100644 --- a/tests/src/smtp/outbound/tls.rs +++ b/tests/src/smtp/outbound/tls.rs @@ -12,8 +12,8 @@ use store::write::now; use crate::smtp::{ inbound::TestMessage, - outbound::TestServer, session::{TestSession, VerifyResponse}, + TestSMTP, }; const LOCAL: &str = r#" @@ -47,11 +47,11 @@ async fn starttls_optional() { crate::enable_logging(); // Start test server - let mut remote = TestServer::new("smtp_starttls_remote", REMOTE, true).await; + let mut remote = TestSMTP::new("smtp_starttls_remote", REMOTE).await; let _rx = remote.start(&[ServerProtocol::Smtp]).await; // Retry on failed STARTTLS - let mut local = TestServer::new("smtp_starttls_local", LOCAL, true).await; + let mut local = TestSMTP::new("smtp_starttls_local", LOCAL).await; // Add mock DNS entries let core = local.build_smtp(); @@ -77,12 +77,12 @@ async fn starttls_optional() { .send_message("john@test.org", &["bill@foobar.org"], "test:no_dkim", "250") .await; local - .qr + .queue_receiver .expect_message_then_deliver() .await .try_deliver(core.clone()) .await; - let mut retry = local.qr.expect_message().await; + let mut retry = local.queue_receiver.expect_message().await; let prev_due = retry.domains[0].retry.due; let next_due = now(); let queue_id = retry.queue_id; @@ -91,17 +91,17 @@ async fn starttls_optional() { .save_changes(&core, prev_due.into(), next_due.into()) .await; local - .qr + .queue_receiver .delivery_attempt(queue_id) .await .try_deliver(core.clone()) .await; tokio::time::sleep(Duration::from_millis(100)).await; remote - .qr + .queue_receiver .expect_message() .await - .read_lines(&remote.qr) + .read_lines(&remote.queue_receiver) .await .assert_not_contains("using TLSv1.3 with cipher"); } diff --git a/tests/src/smtp/queue/concurrent.rs b/tests/src/smtp/queue/concurrent.rs index 8f40e231..ef66190f 100644 --- a/tests/src/smtp/queue/concurrent.rs +++ b/tests/src/smtp/queue/concurrent.rs @@ -9,7 +9,7 @@ use std::time::{Duration, Instant}; use common::config::server::ServerProtocol; use mail_auth::MX; -use crate::smtp::{outbound::TestServer, session::TestSession}; +use crate::smtp::{session::TestSession, TestSMTP}; use smtp::queue::manager::Queue; const LOCAL: &str = r#" @@ -37,10 +37,10 @@ async fn concurrent_queue() { crate::enable_logging(); // Start test server - let remote = TestServer::new("smtp_concurrent_queue_remote", REMOTE, true).await; + let remote = TestSMTP::new("smtp_concurrent_queue_remote", REMOTE).await; let _rx = remote.start(&[ServerProtocol::Smtp]).await; - let local = TestServer::new("smtp_concurrent_queue_local", LOCAL, true).await; + let local = TestSMTP::new("smtp_concurrent_queue_local", LOCAL).await; // Add mock DNS entries let core = local.build_smtp(); @@ -72,22 +72,22 @@ async fn concurrent_queue() { // Spawn 20 concurrent queues at different times for _ in 0..10 { - let local = local.instance.clone(); + let local = local.server.clone(); tokio::spawn(async move { - Queue::new(local).process_events().await; + Queue::new(local.inner).process_events().await; }); } tokio::time::sleep(Duration::from_millis(500)).await; for _ in 0..10 { - let local = local.instance.clone(); + let local = local.server.clone(); tokio::spawn(async move { - Queue::new(local).process_events().await; + Queue::new(local.inner).process_events().await; }); } tokio::time::sleep(Duration::from_millis(1500)).await; - local.qr.assert_queue_is_empty().await; - let remote_messages = remote.qr.read_queued_messages().await; + local.queue_receiver.assert_queue_is_empty().await; + let remote_messages = remote.queue_receiver.read_queued_messages().await; assert_eq!(remote_messages.len(), 100); // Make sure local store is queue diff --git a/tests/src/smtp/queue/dsn.rs b/tests/src/smtp/queue/dsn.rs index 9397edee..75624ba9 100644 --- a/tests/src/smtp/queue/dsn.rs +++ b/tests/src/smtp/queue/dsn.rs @@ -10,9 +10,9 @@ use smtp_proto::{Response, RCPT_NOTIFY_DELAY, RCPT_NOTIFY_FAILURE, RCPT_NOTIFY_S use store::write::now; use utils::BlobHash; -use crate::smtp::{inbound::sign::SIGNATURES, outbound::TestServer, QueueReceiver}; +use crate::smtp::{inbound::sign::SIGNATURES, QueueReceiver, TestSMTP}; use smtp::queue::{ - Domain, Error, ErrorDetails, HostResponse, Message, Recipient, Schedule, Status, + dsn::SendDsn, Domain, Error, ErrorDetails, HostResponse, Message, Recipient, Schedule, Status, }; const CONFIG: &str = r#" @@ -92,9 +92,9 @@ async fn generate_dsn() { }; // Load config - let mut local = TestServer::new("smtp_dsn_test", CONFIG.to_string() + SIGNATURES, true).await; + let mut local = TestSMTP::new("smtp_dsn_test", CONFIG.to_string() + SIGNATURES).await; let core = local.build_smtp(); - let qr = &mut local.qr; + let qr = &mut local.queue_receiver; // Create temp dir for queue qr.blob_store diff --git a/tests/src/smtp/queue/manager.rs b/tests/src/smtp/queue/manager.rs index 58b749c2..2f9684cf 100644 --- a/tests/src/smtp/queue/manager.rs +++ b/tests/src/smtp/queue/manager.rs @@ -8,10 +8,10 @@ use std::time::Duration; use mail_auth::hickory_resolver::proto::op::ResponseCode; -use smtp::queue::{Domain, Message, Schedule, Status}; +use smtp::queue::{spool::SmtpSpool, Domain, Message, Schedule, Status}; use store::write::now; -use crate::smtp::outbound::TestServer; +use crate::smtp::TestSMTP; const CONFIG: &str = r#" [session.ehlo] @@ -26,9 +26,9 @@ async fn queue_due() { // Enable logging crate::enable_logging(); - let local = TestServer::new("smtp_queue_due_test", CONFIG, true).await; + let local = TestSMTP::new("smtp_queue_due_test", CONFIG).await; let core = local.build_smtp(); - let qr = &local.qr; + let qr = &local.queue_receiver; let mut message = new_message(0); message.domains.push(domain("c", 3, 8, 9)); diff --git a/tests/src/smtp/queue/retry.rs b/tests/src/smtp/queue/retry.rs index aaaaea60..090ca34e 100644 --- a/tests/src/smtp/queue/retry.rs +++ b/tests/src/smtp/queue/retry.rs @@ -8,10 +8,11 @@ use std::time::Duration; use crate::smtp::{ inbound::{TestMessage, TestQueueEvent}, - outbound::TestServer, session::{TestSession, VerifyResponse}, + TestSMTP, }; -use smtp::queue::{DeliveryAttempt, Event}; +use common::ipc::QueueEvent; +use smtp::queue::{spool::SmtpSpool, DeliveryAttempt}; use store::write::now; const CONFIG: &str = r#" @@ -39,12 +40,12 @@ async fn queue_retry() { crate::enable_logging(); // Create temp dir for queue - let mut local = TestServer::new("smtp_queue_retry_test", CONFIG, true).await; + let mut local = TestSMTP::new("smtp_queue_retry_test", CONFIG).await; // Create test message let core = local.build_smtp(); let mut session = local.new_session(); - let qr = &mut local.qr; + let qr = &mut local.queue_receiver; session.data.remote_ip_str = "10.0.0.1".to_string(); session.eval_session_params().await; @@ -85,9 +86,9 @@ async fn queue_retry() { attempt.try_deliver(core.clone()).await; loop { match qr.try_read_event().await { - Some(Event::Reload) => {} - Some(Event::OnHold(_)) => unreachable!(), - None | Some(Event::Stop) => break, + Some(QueueEvent::Reload) => {} + Some(QueueEvent::OnHold(_)) => unreachable!(), + None | Some(QueueEvent::Stop) => break, } let now = now(); diff --git a/tests/src/smtp/reporting/analyze.rs b/tests/src/smtp/reporting/analyze.rs index 9a28ae1d..529f7e58 100644 --- a/tests/src/smtp/reporting/analyze.rs +++ b/tests/src/smtp/reporting/analyze.rs @@ -6,7 +6,7 @@ use std::time::Duration; -use crate::smtp::{inbound::TestQueueEvent, outbound::TestServer, session::TestSession}; +use crate::smtp::{inbound::TestQueueEvent, session::TestSession, TestSMTP}; use store::{ write::{ReportClass, ValueClass}, @@ -32,11 +32,11 @@ async fn report_analyze() { crate::enable_logging(); // Create temp dir for queue - let mut local = TestServer::new("smtp_analyze_report_test", CONFIG, true).await; + let mut local = TestSMTP::new("smtp_analyze_report_test", CONFIG).await; // Create test message let mut session = local.new_session(); - let qr = &mut local.qr; + let qr = &mut local.queue_receiver; session.data.remote_ip_str = "10.0.0.1".to_string(); session.eval_session_params().await; session.ehlo("mx.test.org").await; diff --git a/tests/src/smtp/reporting/dmarc.rs b/tests/src/smtp/reporting/dmarc.rs index 5e4ea4be..363f3007 100644 --- a/tests/src/smtp/reporting/dmarc.rs +++ b/tests/src/smtp/reporting/dmarc.rs @@ -10,20 +10,19 @@ use std::{ time::{Duration, Instant}, }; -use common::config::smtp::report::AggregateFrequency; +use common::{config::smtp::report::AggregateFrequency, ipc::DmarcEvent}; use mail_auth::{ common::parse::TxtRecordParser, dmarc::Dmarc, report::{ActionDisposition, Disposition, DmarcResult, Record, Report}, }; +use smtp::reporting::dmarc::DmarcReporting; use store::write::QueueClass; -use smtp::reporting::DmarcEvent; - use crate::smtp::{ inbound::{sign::SIGNATURES, TestMessage}, - outbound::TestServer, session::VerifyResponse, + TestSMTP, }; const CONFIG: &str = r#" @@ -53,12 +52,7 @@ async fn report_dmarc() { crate::enable_logging(); // Create scheduler - let mut local = TestServer::new( - "smtp_report_dmarc_test", - CONFIG.to_string() + SIGNATURES, - true, - ) - .await; + let mut local = TestSMTP::new("smtp_report_dmarc_test", CONFIG.to_string() + SIGNATURES).await; // Authorize external report for foobar.org let core = local.build_smtp(); @@ -67,7 +61,7 @@ async fn report_dmarc() { Dmarc::parse(b"v=DMARC1;").unwrap(), Instant::now() + Duration::from_secs(10), ); - let qr = &mut local.qr; + let qr = &mut local.queue_receiver; // Schedule two events with a same policy and another one with a different policy let dmarc_record = Arc::new( diff --git a/tests/src/smtp/reporting/scheduler.rs b/tests/src/smtp/reporting/scheduler.rs index 4b9b5d97..306339ef 100644 --- a/tests/src/smtp/reporting/scheduler.rs +++ b/tests/src/smtp/reporting/scheduler.rs @@ -6,7 +6,10 @@ use std::sync::Arc; -use common::config::smtp::report::AggregateFrequency; +use common::{ + config::smtp::report::AggregateFrequency, + ipc::{DmarcEvent, PolicyType, TlsEvent}, +}; use mail_auth::{ common::parse::TxtRecordParser, dmarc::{Dmarc, URI}, @@ -15,8 +18,12 @@ use mail_auth::{ }; use store::write::QueueClass; -use crate::smtp::outbound::TestServer; -use smtp::reporting::{dmarc::DmarcFormat, DmarcEvent, PolicyType, TlsEvent}; +use smtp::reporting::{ + dmarc::{DmarcFormat, DmarcReporting}, + tls::TlsReporting, +}; + +use crate::smtp::TestSMTP; const CONFIG: &str = r#" [session.rcpt] @@ -37,9 +44,9 @@ async fn report_scheduler() { crate::enable_logging(); // Create scheduler - let local = TestServer::new("smtp_report_queue_test", CONFIG, true).await; + let local = TestSMTP::new("smtp_report_queue_test", CONFIG).await; let core = local.build_smtp(); - let qr = &local.qr; + let qr = &local.queue_receiver; // Schedule two events with a same policy and another one with a different policy let dmarc_record = diff --git a/tests/src/smtp/reporting/tls.rs b/tests/src/smtp/reporting/tls.rs index e64d5234..dc2d550e 100644 --- a/tests/src/smtp/reporting/tls.rs +++ b/tests/src/smtp/reporting/tls.rs @@ -6,7 +6,7 @@ use std::{io::Read, sync::Arc, time::Duration}; -use common::config::smtp::report::AggregateFrequency; +use common::{config::smtp::report::AggregateFrequency, ipc::TlsEvent}; use mail_auth::{ common::parse::TxtRecordParser, flate2::read::GzDecoder, @@ -15,12 +15,12 @@ use mail_auth::{ }; use store::write::QueueClass; -use smtp::reporting::{tls::TLS_HTTP_REPORT, TlsEvent}; +use smtp::reporting::tls::{TlsReporting, TLS_HTTP_REPORT}; use crate::smtp::{ inbound::{sign::SIGNATURES, TestMessage}, - outbound::TestServer, session::VerifyResponse, + TestSMTP, }; const CONFIG: &str = r#" @@ -46,14 +46,9 @@ async fn report_tls() { crate::enable_logging(); // Create scheduler - let mut local = TestServer::new( - "smtp_report_tls_test", - CONFIG.to_string() + SIGNATURES, - true, - ) - .await; + let mut local = TestSMTP::new("smtp_report_tls_test", CONFIG.to_string() + SIGNATURES).await; let core = local.build_smtp(); - let qr = &mut local.qr; + let qr = &mut local.queue_receiver; // Schedule TLS reports to be delivered via email let tls_record = Arc::new(TlsRpt::parse(b"v=TLSRPTv1;rua=mailto:reports@foobar.org").unwrap()); @@ -62,7 +57,7 @@ async fn report_tls() { // Add two successful records core.schedule_tls(Box::new(TlsEvent { domain: "foobar.org".to_string(), - policy: smtp::reporting::PolicyType::None, + policy: common::ipc::PolicyType::None, failure: None, tls_record: tls_record.clone(), interval: AggregateFrequency::Daily, @@ -72,23 +67,20 @@ async fn report_tls() { for (policy, rt) in [ ( - smtp::reporting::PolicyType::None, // Quota limited at 1532 bytes, this should not be included in the report. + common::ipc::PolicyType::None, // Quota limited at 1532 bytes, this should not be included in the report. ResultType::CertificateExpired, ), + (common::ipc::PolicyType::Tlsa(None), ResultType::TlsaInvalid), ( - smtp::reporting::PolicyType::Tlsa(None), - ResultType::TlsaInvalid, - ), - ( - smtp::reporting::PolicyType::Sts(None), + common::ipc::PolicyType::Sts(None), ResultType::StsPolicyFetchError, ), ( - smtp::reporting::PolicyType::Sts(None), + common::ipc::PolicyType::Sts(None), ResultType::StsPolicyInvalid, ), ( - smtp::reporting::PolicyType::Sts(None), + common::ipc::PolicyType::Sts(None), ResultType::StsWebpkiInvalid, ), ] { @@ -192,7 +184,7 @@ async fn report_tls() { // Add two successful records core.schedule_tls(Box::new(TlsEvent { domain: "foobar.org".to_string(), - policy: smtp::reporting::PolicyType::None, + policy: common::ipc::PolicyType::None, failure: None, tls_record: tls_record.clone(), interval: AggregateFrequency::Daily, diff --git a/tests/src/smtp/session.rs b/tests/src/smtp/session.rs index fd1173c0..3ba4d837 100644 --- a/tests/src/smtp/session.rs +++ b/tests/src/smtp/session.rs @@ -9,6 +9,7 @@ use std::{borrow::Cow, path::PathBuf, sync::Arc}; use common::{ config::server::ServerProtocol, listener::{limiter::ConcurrencyLimiter, ServerInstance, SessionStream, TcpAcceptor}, + Server, }; use rustls::{server::ResolvesServerCert, ServerConfig}; use tokio::{ @@ -16,7 +17,7 @@ use tokio::{ sync::watch, }; -use smtp::core::{Session, SessionAddress, SessionData, SessionParameters, State, SMTP}; +use smtp::core::{Session, SessionAddress, SessionData, SessionParameters, State}; use tokio_rustls::TlsAcceptor; use utils::snowflake::SnowflakeIdGenerator; @@ -81,8 +82,8 @@ impl Unpin for DummyIo {} #[allow(async_fn_in_trait)] pub trait TestSession { - fn test(core: SMTP) -> Self; - fn test_with_shutdown(core: SMTP, shutdown_rx: watch::Receiver<bool>) -> Self; + fn test(server: Server) -> Self; + fn test_with_shutdown(server: Server, shutdown_rx: watch::Receiver<bool>) -> Self; fn response(&mut self) -> Vec<String>; fn write_rx(&mut self, data: &str); async fn rset(&mut self); @@ -96,11 +97,11 @@ pub trait TestSession { } impl TestSession for Session<DummyIo> { - fn test_with_shutdown(core: SMTP, shutdown_rx: watch::Receiver<bool>) -> Self { + fn test_with_shutdown(server: Server, shutdown_rx: watch::Receiver<bool>) -> Self { Self { state: State::default(), instance: Arc::new(ServerInstance::test_with_shutdown(shutdown_rx)), - core, + server, stream: DummyIo { rx_buf: vec![], tx_buf: vec![], @@ -119,8 +120,8 @@ impl TestSession for Session<DummyIo> { } } - fn test(core: SMTP) -> Self { - Self::test_with_shutdown(core, watch::channel(false).1) + fn test(server: Server) -> Self { + Self::test_with_shutdown(server, watch::channel(false).1) } fn response(&mut self) -> Vec<String> { @@ -258,7 +259,7 @@ impl TestSession for Session<DummyIo> { dsn_info: None, }, ], - self.core.inner.queue_id_gen.generate().unwrap(), + self.server.inner.data.queue_id_gen.generate().unwrap(), 0, ) .await; |