use std::sync::atomic::AtomicUsize;
use std::sync::{atomic, Arc};
use async_trait::async_trait;
use miette::{ErrReport, Result};
use miltr_common::modifications::headers::AddHeader;
use miltr_common::modifications::ModificationResponse;
use miltr_server::Milter;
use crate::utils::TestCase;
const MAILS_COUNT: usize = 5;
#[derive(Debug, Clone)]
struct AddHeaderTestMilter {
end_of_body_called: Arc<AtomicUsize>,
}
impl AddHeaderTestMilter {
pub fn new() -> Self {
Self {
end_of_body_called: Arc::new(AtomicUsize::new(0)),
}
}
pub fn end_of_body_called(&self) -> usize {
self.end_of_body_called
.as_ref()
.load(atomic::Ordering::SeqCst)
}
}
#[async_trait]
impl Milter for AddHeaderTestMilter {
type Error = ErrReport;
async fn end_of_body(&mut self) -> std::result::Result<ModificationResponse, Self::Error> {
self.end_of_body_called
.fetch_add(1, atomic::Ordering::SeqCst);
let mut builder = ModificationResponse::builder();
builder.push(AddHeader::new(b"name", b"value"));
builder.push(AddHeader::new(b"name1", b"value1"));
let response = builder.contin();
Ok(response)
}
async fn abort(&mut self) -> std::result::Result<(), Self::Error> {
Ok(())
}
}
#[tokio::test]
async fn test_many_mail_send() -> Result<()> {
let milter = AddHeaderTestMilter::new();
let testcase = TestCase::setup("many-mail-send", milter.clone()).await?;
let mut transport = testcase.create_smtp_transport().await;
for i in 0..MAILS_COUNT {
if transport.has_broken() {
break;
}
println!("Sending email num {}", i + 1);
let _ = testcase
.send_mail_with_transport(&mut transport)
.await
.map_err(|e| println!("Error on send mails: {e}"));
}
transport.abort().await;
let testcase = testcase.stop().await.expect("Failed to shut down postfix");
let content = testcase.log_file_content().await?;
assert!(!content.contains("unexpected filter response"));
assert_eq!(milter.end_of_body_called(), MAILS_COUNT);
assert_eq!(testcase.milter_connections_count(), 1);
Ok(())
}