Skip to main content

rusmes_loadtest/protocols/
pop3.rs

1//! POP3 client for load testing
2
3use anyhow::{Context, Result};
4use std::time::Duration;
5use tokio::io::{AsyncReadExt, AsyncWriteExt};
6use tokio::net::TcpStream;
7use tokio::time::timeout;
8
9/// POP3 client for load testing
10pub struct Pop3Client;
11
12impl Pop3Client {
13    /// Retrieve messages via POP3
14    pub async fn retrieve_messages(host: &str, port: u16) -> Result<usize> {
15        let addr = format!("{}:{}", host, port);
16
17        let connect_timeout = Duration::from_secs(5);
18        let stream = timeout(connect_timeout, TcpStream::connect(&addr))
19            .await
20            .context("Connection timeout")?
21            .context("Failed to connect")?;
22
23        let mut stream = stream;
24        let mut buffer = vec![0u8; 4096];
25
26        // Read greeting
27        let n = timeout(Duration::from_secs(5), stream.read(&mut buffer))
28            .await
29            .context("Read timeout")?
30            .context("Failed to read greeting")?;
31
32        let mut bytes_received = n;
33
34        // USER
35        stream.write_all(b"USER testuser\r\n").await?;
36        let n = stream.read(&mut buffer).await?;
37        bytes_received += n;
38
39        // PASS
40        stream.write_all(b"PASS testpass\r\n").await?;
41        let n = stream.read(&mut buffer).await?;
42        bytes_received += n;
43
44        // STAT (get mailbox statistics)
45        stream.write_all(b"STAT\r\n").await?;
46        let n = stream.read(&mut buffer).await?;
47        bytes_received += n;
48
49        // LIST (list messages)
50        stream.write_all(b"LIST\r\n").await?;
51        let n = stream.read(&mut buffer).await?;
52        bytes_received += n;
53
54        // RETR 1 (retrieve first message)
55        stream.write_all(b"RETR 1\r\n").await?;
56        let n = stream.read(&mut buffer).await?;
57        bytes_received += n;
58
59        // QUIT
60        stream.write_all(b"QUIT\r\n").await?;
61        let _ = stream.read(&mut buffer).await;
62
63        Ok(bytes_received)
64    }
65
66    /// Delete messages via POP3
67    pub async fn delete_messages(host: &str, port: u16) -> Result<usize> {
68        let addr = format!("{}:{}", host, port);
69
70        let connect_timeout = Duration::from_secs(5);
71        let stream = timeout(connect_timeout, TcpStream::connect(&addr))
72            .await
73            .context("Connection timeout")?
74            .context("Failed to connect")?;
75
76        let mut stream = stream;
77        let mut buffer = vec![0u8; 4096];
78
79        // Read greeting
80        let n = timeout(Duration::from_secs(5), stream.read(&mut buffer))
81            .await
82            .context("Read timeout")?
83            .context("Failed to read greeting")?;
84
85        let mut bytes_received = n;
86
87        // USER
88        stream.write_all(b"USER testuser\r\n").await?;
89        let n = stream.read(&mut buffer).await?;
90        bytes_received += n;
91
92        // PASS
93        stream.write_all(b"PASS testpass\r\n").await?;
94        let n = stream.read(&mut buffer).await?;
95        bytes_received += n;
96
97        // DELE 1 (mark for deletion)
98        stream.write_all(b"DELE 1\r\n").await?;
99        let n = stream.read(&mut buffer).await?;
100        bytes_received += n;
101
102        // QUIT (commit deletions)
103        stream.write_all(b"QUIT\r\n").await?;
104        let _ = stream.read(&mut buffer).await;
105
106        Ok(bytes_received)
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113
114    #[tokio::test]
115    async fn test_pop3_client_timeout() {
116        // Test connection timeout to non-existent host
117        let result = Pop3Client::retrieve_messages("192.0.2.1", 110).await;
118        assert!(result.is_err());
119    }
120
121    #[tokio::test]
122    async fn test_pop3_delete_timeout() {
123        // Test connection timeout to non-existent host
124        let result = Pop3Client::delete_messages("192.0.2.1", 110).await;
125        assert!(result.is_err());
126    }
127}