Merge pull request #228 from urkle/feat-cyrus-testing-setup

This commit is contained in:
Jon Gjengset 2022-07-26 04:20:30 -07:00
commit 1ce44011ba
3 changed files with 111 additions and 20 deletions

View file

@ -6,7 +6,7 @@ name: cargo test
jobs: jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: ${{ matrix.toolchain }} name: greenmail/${{ matrix.toolchain }}
strategy: strategy:
matrix: matrix:
toolchain: [stable, beta, nightly] toolchain: [stable, beta, nightly]
@ -32,3 +32,28 @@ jobs:
- 3995:3995 - 3995:3995
env: env:
GREENMAIL_OPTS: "-Dgreenmail.setup.test.all -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled -Dgreenmail.verbose" GREENMAIL_OPTS: "-Dgreenmail.setup.test.all -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled -Dgreenmail.verbose"
test_cyrus:
runs-on: ubuntu-latest
name: cyrus/${{ matrix.toolchain }}
strategy:
matrix:
toolchain: [stable, beta, nightly]
steps:
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.toolchain }}
- uses: actions/checkout@v2
- name: cargo test
uses: actions-rs/cargo@v1
with:
command: test
args: -- --ignored
services:
cyrus_imapd:
image: outoforder/cyrus-imapd-tester:latest
ports:
- 3025:25
- 3143:143
- 3465:465
- 3993:993

View file

@ -92,7 +92,14 @@ easiest way to do that is with Docker:
```console ```console
$ docker pull greenmail/standalone:1.6.8 $ docker pull greenmail/standalone:1.6.8
$ docker run -t -i -e GREENMAIL_OPTS='-Dgreenmail.setup.test.all -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled -Dgreenmail.verbose' -p 3025:3025 -p 3110:3110 -p 3143:3143 -p 3465:3465 -p 3993:3993 -p 3995:3995 greenmail/standalone:1.6.3 $ docker run -it --rm -e GREENMAIL_OPTS='-Dgreenmail.setup.test.all -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled -Dgreenmail.verbose' -p 3025:3025 -p 3110:3110 -p 3143:3143 -p 3465:3465 -p 3993:3993 -p 3995:3995 greenmail/standalone:1.6.3
```
Another alternative is to test against cyrus imapd which is a more complete IMAP implementation that greenmail (supporting quotas and ACLs).
```
$ docker pull outoforder/cyrus-imapd-tester
$ docker run -it --rm -p 3025:25 -p 3110:110 -p 3143:143 -p 3465:465 -p 3993:993 outoforder/cyrus-imapd-tester:latest
``` ```
## License ## License

View file

@ -19,9 +19,61 @@ fn tls() -> native_tls::TlsConnector {
.unwrap() .unwrap()
} }
fn test_host() -> String {
std::env::var("TEST_HOST").unwrap_or("127.0.0.1".to_string())
}
fn test_smtp_host() -> String {
std::env::var("TEST_SMTP_HOST")
.unwrap_or_else(|_| std::env::var("TEST_HOST").unwrap_or("127.0.0.1".to_string()))
}
fn test_imap_port() -> u16 {
std::env::var("TEST_IMAP_PORT")
.unwrap_or("3143".to_string())
.parse()
.unwrap_or(3143)
}
fn test_imaps_port() -> u16 {
std::env::var("TEST_IMAPS_PORT")
.unwrap_or("3993".to_string())
.parse()
.unwrap_or(3993)
}
fn test_smtps_port() -> u16 {
std::env::var("TEST_SMTPS_PORT")
.unwrap_or("3465".to_string())
.parse()
.unwrap_or(3465)
}
fn clean_mailbox(session: &mut imap::Session<native_tls::TlsStream<TcpStream>>) {
session.select("INBOX").unwrap();
let inbox = session.search("ALL").unwrap();
if !inbox.is_empty() {
session
.store(
inbox
.iter()
.map(|d| d.to_string())
.collect::<Vec<String>>()
.join(","),
"+FLAGS (\\Deleted)",
)
.unwrap();
}
session.expunge().unwrap();
}
fn wait_for_delivery() {
std::thread::sleep(std::time::Duration::from_millis(500));
}
fn session(user: &str) -> imap::Session<native_tls::TlsStream<TcpStream>> { fn session(user: &str) -> imap::Session<native_tls::TlsStream<TcpStream>> {
let host = std::env::var("TEST_HOST").unwrap_or("127.0.0.1".to_string()); let host = test_host();
let mut s = imap::ClientBuilder::new(&host, 3993) let mut s = imap::ClientBuilder::new(&host, test_imaps_port())
.connect(|domain, tcp| { .connect(|domain, tcp| {
let ssl_conn = tls(); let ssl_conn = tls();
Ok(native_tls::TlsConnector::connect(&ssl_conn, domain, tcp).unwrap()) Ok(native_tls::TlsConnector::connect(&ssl_conn, domain, tcp).unwrap())
@ -30,19 +82,17 @@ fn session(user: &str) -> imap::Session<native_tls::TlsStream<TcpStream>> {
.login(user, user) .login(user, user)
.unwrap(); .unwrap();
s.debug = true; s.debug = true;
clean_mailbox(&mut s);
s s
} }
fn smtp(user: &str) -> lettre::SmtpTransport { fn smtp(user: &str) -> lettre::SmtpTransport {
let creds = lettre::smtp::authentication::Credentials::new(user.to_string(), user.to_string()); let creds = lettre::smtp::authentication::Credentials::new(user.to_string(), user.to_string());
lettre::SmtpClient::new( lettre::SmtpClient::new(
&format!( &format!("{}:{}", test_smtp_host(), test_smtps_port()),
"{}:3465",
std::env::var("TEST_HOST").unwrap_or("127.0.0.1".to_string())
),
lettre::ClientSecurity::Wrapper(lettre::ClientTlsParameters { lettre::ClientSecurity::Wrapper(lettre::ClientTlsParameters {
connector: tls(), connector: tls(),
domain: "smpt.example.com".to_string(), domain: "smtp.example.com".to_string(),
}), }),
) )
.unwrap() .unwrap()
@ -53,9 +103,9 @@ fn smtp(user: &str) -> lettre::SmtpTransport {
#[test] #[test]
#[ignore] #[ignore]
fn connect_insecure_then_secure() { fn connect_insecure_then_secure() {
let host = std::env::var("TEST_HOST").unwrap_or("127.0.0.1".to_string()); let host = test_host();
// ignored because of https://github.com/greenmail-mail-test/greenmail/issues/135 // ignored because of https://github.com/greenmail-mail-test/greenmail/issues/135
imap::ClientBuilder::new(&host, 3143) imap::ClientBuilder::new(&host, test_imap_port())
.starttls() .starttls()
.connect(|domain, tcp| { .connect(|domain, tcp| {
let ssl_conn = tls(); let ssl_conn = tls();
@ -66,8 +116,8 @@ fn connect_insecure_then_secure() {
#[test] #[test]
fn connect_secure() { fn connect_secure() {
let host = std::env::var("TEST_HOST").unwrap_or("127.0.0.1".to_string()); let host = test_host();
imap::ClientBuilder::new(&host, 3993) imap::ClientBuilder::new(&host, test_imaps_port())
.connect(|domain, tcp| { .connect(|domain, tcp| {
let ssl_conn = tls(); let ssl_conn = tls();
Ok(native_tls::TlsConnector::connect(&ssl_conn, domain, tcp).unwrap()) Ok(native_tls::TlsConnector::connect(&ssl_conn, domain, tcp).unwrap())
@ -124,6 +174,8 @@ fn inbox() {
.unwrap(); .unwrap();
s.send(e.into()).unwrap(); s.send(e.into()).unwrap();
wait_for_delivery();
// now we should see the e-mails! // now we should see the e-mails!
let inbox = c.search("ALL").unwrap(); let inbox = c.search("ALL").unwrap();
assert_eq!(inbox.len(), 2); assert_eq!(inbox.len(), 2);
@ -145,12 +197,11 @@ fn inbox() {
.any(|m| m == &imap::types::UnsolicitedResponse::Recent(2))); .any(|m| m == &imap::types::UnsolicitedResponse::Recent(2)));
// let's see that we can also fetch the e-mails // let's see that we can also fetch the e-mails
let fetch = c.fetch("1", "(ALL UID)").unwrap(); let fetch = c.fetch("1", "(ENVELOPE INTERNALDATE UID)").unwrap();
assert_eq!(fetch.len(), 1); assert_eq!(fetch.len(), 1);
let fetch = fetch.iter().next().unwrap(); let fetch = fetch.iter().next().unwrap();
assert_eq!(fetch.message, 1); assert_eq!(fetch.message, 1);
assert_ne!(fetch.uid, None); assert_ne!(fetch.uid, None);
assert_eq!(fetch.size, Some(138));
let e = fetch.envelope().unwrap(); let e = fetch.envelope().unwrap();
assert_eq!(e.subject, Some(b"My first e-mail"[..].into())); assert_eq!(e.subject, Some(b"My first e-mail"[..].into()));
assert_ne!(e.from, None); assert_ne!(e.from, None);
@ -240,6 +291,8 @@ fn inbox_uid() {
.unwrap(); .unwrap();
s.send(e.into()).unwrap(); s.send(e.into()).unwrap();
wait_for_delivery();
// now we should see the e-mail! // now we should see the e-mail!
let inbox = c let inbox = c
.uid_sort(&[SortCriterion::Subject], SortCharset::Utf8, "ALL") .uid_sort(&[SortCriterion::Subject], SortCharset::Utf8, "ALL")
@ -263,7 +316,9 @@ fn inbox_uid() {
.any(|m| m == &imap::types::UnsolicitedResponse::Recent(1))); .any(|m| m == &imap::types::UnsolicitedResponse::Recent(1)));
// let's see that we can also fetch the e-mail // let's see that we can also fetch the e-mail
let fetch = c.uid_fetch(format!("{}", uid), "(ALL UID)").unwrap(); let fetch = c
.uid_fetch(format!("{}", uid), "(ENVELOPE INTERNALDATE FLAGS UID)")
.unwrap();
assert_eq!(fetch.len(), 1); assert_eq!(fetch.len(), 1);
let fetch = fetch.iter().next().unwrap(); let fetch = fetch.iter().next().unwrap();
assert_eq!(fetch.uid, Some(uid)); assert_eq!(fetch.uid, Some(uid));
@ -288,7 +343,7 @@ fn list() {
let mut s = session("readonly-test@localhost"); let mut s = session("readonly-test@localhost");
s.select("INBOX").unwrap(); s.select("INBOX").unwrap();
let subdirs = s.list(None, Some("%")).unwrap(); let subdirs = s.list(None, Some("%")).unwrap();
assert_eq!(subdirs.len(), 0); assert_eq!(subdirs.len(), 1);
// TODO: make a subdir // TODO: make a subdir
} }
@ -323,7 +378,7 @@ fn append() {
let uid = inbox.into_iter().next().unwrap(); let uid = inbox.into_iter().next().unwrap();
// fetch the e-mail // fetch the e-mail
let fetch = c.uid_fetch(format!("{}", uid), "(ALL UID)").unwrap(); let fetch = c.uid_fetch(format!("{}", uid), "(ENVELOPE UID)").unwrap();
assert_eq!(fetch.len(), 1); assert_eq!(fetch.len(), 1);
let fetch = fetch.iter().next().unwrap(); let fetch = fetch.iter().next().unwrap();
assert_eq!(fetch.uid, Some(uid)); assert_eq!(fetch.uid, Some(uid));
@ -374,7 +429,9 @@ fn append_with_flags() {
let uid = inbox.into_iter().next().unwrap(); let uid = inbox.into_iter().next().unwrap();
// fetch the e-mail // fetch the e-mail
let fetch = c.uid_fetch(format!("{}", uid), "(ALL UID)").unwrap(); let fetch = c
.uid_fetch(format!("{}", uid), "(ENVELOPE FLAGS UID)")
.unwrap();
assert_eq!(fetch.len(), 1); assert_eq!(fetch.len(), 1);
let fetch = fetch.iter().next().unwrap(); let fetch = fetch.iter().next().unwrap();
assert_eq!(fetch.uid, Some(uid)); assert_eq!(fetch.uid, Some(uid));
@ -434,7 +491,9 @@ fn append_with_flags_and_date() {
let uid = inbox.into_iter().next().unwrap(); let uid = inbox.into_iter().next().unwrap();
// fetch the e-mail // fetch the e-mail
let fetch = c.uid_fetch(format!("{}", uid), "(ALL UID)").unwrap(); let fetch = c
.uid_fetch(format!("{}", uid), "(INTERNALDATE UID)")
.unwrap();
assert_eq!(fetch.len(), 1); assert_eq!(fetch.len(), 1);
let fetch = fetch.iter().next().unwrap(); let fetch = fetch.iter().next().unwrap();
assert_eq!(fetch.uid, Some(uid)); assert_eq!(fetch.uid, Some(uid));