Java tutorial
/* * ***** BEGIN LICENSE BLOCK ***** * Zimbra Collaboration Suite Server * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2016 Synacor, Inc. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software Foundation, * version 2 of the License. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * You should have received a copy of the GNU General Public License along with this program. * If not, see <https://www.gnu.org/licenses/>. * ***** END LICENSE BLOCK ***** */ package com.zimbra.cs.mailclient.smtp; import java.io.OutputStream; import java.util.Properties; import javax.mail.Address; import javax.mail.MessagingException; import javax.mail.SendFailedException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.mail.util.SharedByteArrayInputStream; import org.apache.commons.codec.binary.Base64; import org.junit.After; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import com.google.common.base.Charsets; import com.sun.mail.smtp.SMTPMessage; import com.zimbra.common.zmime.ZMimeMessage; import com.zimbra.cs.mailbox.MailboxTestUtil; import com.zimbra.cs.util.JMSession; import com.zimbra.cs.util.MockTcpServer; /** * Unit test for {@link SmtpTransport}. * * @author ysasaki */ public final class SmtpTransportTest { private static final int PORT = 9025; private MockTcpServer server; @BeforeClass public static void init() throws Exception { MailboxTestUtil.initServer(); } @After public void tearDown() { Properties props = JMSession.getSession().getProperties(); props.remove("mail.smtp.sendpartial"); props.remove("mail.smtp.from"); JMSession.getSession().getProperties().remove("mail.smtp.sendpartial"); if (server != null) { server.destroy(); } } @Test(timeout = 3000) public void send() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("250 OK").recvLine() // DATA .sendLine("354 OK").swallowUntil("\r\n.\r\n").sendLine("250 OK").recvLine() // QUIT .sendLine("221 bye").build().start(PORT); Session session = JMSession.getSession(); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); transport.sendMessage(msg, msg.getAllRecipients()); transport.close(); server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void sendPartially() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO 1 .sendLine("250 OK").recvLine() // RCPT TO 2 .sendLine("550 not found").recvLine() // RCPT TO 3 .sendLine("550 not found").recvLine() // DATA .sendLine("354 OK").swallowUntil("\r\n.\r\n").sendLine("250 OK").recvLine() // QUIT .sendLine("221 bye").build().start(PORT); Session session = JMSession.getSession(); session.getProperties().setProperty("mail.smtp.sendpartial", "true"); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\n" + "To: rcpt1@zimbra.com, rcpt2@zimbra.com, rcpt3@zimbra.com\nSubject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); try { transport.sendMessage(msg, msg.getAllRecipients()); } catch (SendFailedException e) { Assert.assertEquals(1, e.getValidSentAddresses().length); Assert.assertEquals(0, e.getValidUnsentAddresses().length); Assert.assertEquals(2, e.getInvalidAddresses().length); } finally { transport.close(); } server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt1@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt2@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt3@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void mailFromError() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("451 error").recvLine() // QUIT .build().start(PORT); Session session = JMSession.getSession(); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\n" + "Subject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); try { transport.sendMessage(msg, msg.getAllRecipients()); Assert.fail(); } catch (SendFailedException e) { Assert.assertEquals(0, e.getValidSentAddresses().length); Assert.assertEquals(0, e.getValidUnsentAddresses().length); Assert.assertEquals(0, e.getInvalidAddresses().length); } finally { transport.close(); } server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void mailSmtpFrom() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("250 OK").recvLine() // DATA .sendLine("354 OK").swallowUntil("\r\n.\r\n").sendLine("250 OK").recvLine() // QUIT .sendLine("221 bye").build().start(PORT); Session session = JMSession.getSession(); session.getProperties().setProperty("mail.smtp.from", "from@zimbra.com"); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); transport.sendMessage(msg, msg.getAllRecipients()); transport.close(); server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<from@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void nullMailFrom() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("250 OK").recvLine() // DATA .sendLine("354 OK").swallowUntil("\r\n.\r\n").sendLine("250 OK").recvLine() // QUIT .sendLine("221 bye").build().start(PORT); Session session = JMSession.getSession(); session.getProperties().setProperty("mail.smtp.from", "from@zimbra.com"); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\ntest"; SMTPMessage msg = new SMTPMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); msg.setEnvelopeFrom("<>"); // this should override the previously set mail.smtp.from transport.sendMessage(msg, msg.getAllRecipients()); transport.close(); server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void bracketsInMailAndRcpt() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("250 OK").recvLine() // DATA .sendLine("354 OK").swallowUntil("\r\n.\r\n").sendLine("250 OK").recvLine() // QUIT .sendLine("221 bye").build().start(PORT); Session session = JMSession.getSession(); session.getProperties().setProperty("mail.smtp.from", "<>"); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); transport.sendMessage(msg, new Address[] { new InternetAddress("<rcpt@zimbra.com>") }); transport.close(); server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void authLogin() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250-smtp.zimbra.com").sendLine("250 AUTH LOGIN").recvLine() // AUTH LOGIN .sendLine("334 OK").recvLine() // USER .sendLine("334").recvLine() // PASSWORD .sendLine("235 Authentication successful").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("250 OK").recvLine() // DATA .sendLine("354 OK").swallowUntil("\r\n.\r\n").sendLine("250 OK").recvLine() // QUIT .sendLine("221 bye").build().start(PORT); Session session = JMSession.getSession(); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, "zimbra", "secret"); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); transport.sendMessage(msg, msg.getAllRecipients()); transport.close(); server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("AUTH LOGIN\r\n", server.replay()); Assert.assertEquals(base64("zimbra") + "\r\n", server.replay()); Assert.assertEquals(base64("secret") + "\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void authPlain() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250-smtp.zimbra.com").sendLine("250 AUTH PLAIN").recvLine() // AUTH PLAIN initial-response .sendLine("235 Authentication successful").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("250 OK").recvLine() // DATA .sendLine("354 OK").swallowUntil("\r\n.\r\n").sendLine("250 OK").recvLine() // QUIT .sendLine("221 bye").build().start(PORT); Session session = JMSession.getSession(); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, "zimbra", "secret"); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); transport.sendMessage(msg, msg.getAllRecipients()); transport.close(); server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("AUTH PLAIN " + base64("\0zimbra\0secret") + "\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void noAuth() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").build().start(PORT); Session session = JMSession.getSession(); Transport transport = session.getTransport("smtp"); try { transport.connect("localhost", PORT, "zimbra", "secret"); Assert.fail(); } catch (MessagingException e) { Assert.assertEquals("The server doesn't support SMTP-AUTH.", e.getMessage()); } server.shutdown(1000); } @Test(timeout = 3000) public void noAuthMechansims() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250-OK").sendLine("250 AUTH NTLM").build().start(PORT); Session session = JMSession.getSession(); Transport transport = session.getTransport("smtp"); try { transport.connect("localhost", PORT, "zimbra", "secret"); Assert.fail(); } catch (MessagingException e) { Assert.assertEquals("No auth mechanism supported: [NTLM]", e.getMessage()); } server.shutdown(1000); } private String base64(String src) { return new String(Base64.encodeBase64(src.getBytes())); } @Test(timeout = 3000) public void rcptToError() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("550 error").recvLine() // QUIT .build().start(PORT); Session session = JMSession.getSession(); session.getProperties().setProperty("mail.smtp.sendpartial", "true"); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); try { transport.sendMessage(msg, msg.getAllRecipients()); Assert.fail(); } catch (SendFailedException e) { Assert.assertEquals(0, e.getValidSentAddresses().length); Assert.assertEquals(0, e.getValidUnsentAddresses().length); Assert.assertEquals(1, e.getInvalidAddresses().length); } finally { transport.close(); } server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void endOfData() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("250 OK").recvLine() // DATA .sendLine("354 OK").recvUntil("\r\n.\r\n").sendLine("250 OK").recvLine() // QUIT .sendLine("221 bye").build().start(PORT); Session session = JMSession.getSession(); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\n" + ".\n" + "..\n" + ".\n"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); transport.sendMessage(msg, msg.getAllRecipients()); transport.close(); server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertEquals("From: sender@zimbra.com\r\nTo: rcpt@zimbra.com\r\nSubject: test\r\n\r\n" + "..\r\n" + "...\r\n" + "..\r\n" + ".\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void dataError() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("250 OK").recvLine() // DATA .sendLine("451 error").recvLine() // QUIT .build().start(PORT); Session session = JMSession.getSession(); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); try { transport.sendMessage(msg, msg.getAllRecipients()); Assert.fail(); } catch (SendFailedException e) { Assert.assertEquals(1, e.getValidSentAddresses().length); Assert.assertEquals(0, e.getValidUnsentAddresses().length); Assert.assertEquals(0, e.getInvalidAddresses().length); } finally { transport.close(); } server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void dataException() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("250 OK").recvLine() // DATA .sendLine("354 OK").swallowUntil("\r\n.\r\n").build().start(PORT); Session session = JMSession.getSession(); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))) { @Override public void writeTo(OutputStream os, String[] ignoreList) throws MessagingException { throw new MessagingException(); // exception while encoding } }; try { transport.sendMessage(msg, msg.getAllRecipients()); Assert.fail(); } catch (SendFailedException expected) { } finally { transport.close(); } server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void rset() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RSET .sendLine("250 OK").build().start(PORT); Session session = JMSession.getSession(); SmtpTransport transport = (SmtpTransport) session.getTransport("smtp"); try { transport.connect("localhost", PORT, null, null); transport.mail("sender@zimbra.com"); transport.rset(); } finally { transport.close(); } server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RSET\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void quitNoResponse() throws Exception { server = MockTcpServer.scenario().sendLine("220 test ready").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("250 OK").recvLine() // DATA .sendLine("354 OK").swallowUntil("\r\n.\r\n").sendLine("250 OK").recvLine() // QUIT .build().start(PORT); Session session = JMSession.getSession(); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); transport.sendMessage(msg, msg.getAllRecipients()); transport.close(); server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } @Test(timeout = 3000) public void multilineGreeting() throws Exception { server = MockTcpServer.scenario().sendLine("220-first line").sendLine("220 second line").recvLine() // EHLO .sendLine("250 OK").recvLine() // MAIL FROM .sendLine("250 OK").recvLine() // RCPT TO .sendLine("250 OK").recvLine() // DATA .sendLine("354 OK").swallowUntil("\r\n.\r\n").sendLine("250 OK").recvLine() // QUIT .sendLine("221 bye").build().start(PORT); Session session = JMSession.getSession(); Transport transport = session.getTransport("smtp"); transport.connect("localhost", PORT, null, null); String raw = "From: sender@zimbra.com\nTo: rcpt@zimbra.com\nSubject: test\n\ntest"; MimeMessage msg = new ZMimeMessage(session, new SharedByteArrayInputStream(raw.getBytes(Charsets.ISO_8859_1))); transport.sendMessage(msg, msg.getAllRecipients()); transport.close(); server.shutdown(1000); Assert.assertEquals("EHLO localhost\r\n", server.replay()); Assert.assertEquals("MAIL FROM:<sender@zimbra.com>\r\n", server.replay()); Assert.assertEquals("RCPT TO:<rcpt@zimbra.com>\r\n", server.replay()); Assert.assertEquals("DATA\r\n", server.replay()); Assert.assertEquals("QUIT\r\n", server.replay()); Assert.assertNull(server.replay()); } }