package dslab.client; import dslab.*; import dslab.util.Config; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ErrorCollector; import java.util.concurrent.TimeUnit; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.assertThat; /** * Starts a mailbox server and a message client, and injects mails to the mailbox server that are read by the mail * client. Note that your mailbox server should run even if there is no naming service is available. */ public class MessageClientMailboxTest { private static final Log LOG = LogFactory.getLog(MessageClientMailboxTest.class); @Rule public ErrorCollector err = new ErrorCollector(); private Config mailboxConfig; private TestInputStream mailboxServerIn; private TestOutputStream mailboxServerOut; private Thread mailboxServerThread; private TestInputStream messageClientIn; private TestOutputStream messageClientOut; private Thread messageClientThread; @Before public void setUp() throws Exception { LOG.info("Creating mailbox server"); mailboxConfig = new Config("mailbox-earth-planet"); mailboxServerIn = new TestInputStream(); mailboxServerOut = new TestOutputStream(); Runnable mailboxServer = ComponentFactory.createMailboxServer("mailbox-earth-planet", mailboxServerIn, mailboxServerOut); mailboxServerThread = new Thread(mailboxServer); mailboxServerThread.start(); LOG.info("Waiting for mailbox server sockets"); Sockets.waitForSocket("localhost", mailboxConfig.getInt("dmtp.tcp.port"), Constants.COMPONENT_STARTUP_WAIT); Sockets.waitForSocket("localhost", mailboxConfig.getInt("dmap.tcp.port"), Constants.COMPONENT_STARTUP_WAIT); LOG.info("Starting message client"); messageClientIn = new TestInputStream(); messageClientOut = new TestOutputStream(); Runnable messageClient = ComponentFactory.createMessageClient("client-trillian", messageClientIn, messageClientOut); messageClientThread = new Thread(messageClient); messageClientThread.start(); Thread.sleep(Constants.COMPONENT_STARTUP_WAIT); } @After public void tearDown() throws Exception { messageClientIn.addLine("shutdown"); messageClientThread.join(Constants.COMPONENT_TEARDOWN_WAIT); mailboxServerIn.addLine("shutdown"); mailboxServerThread.join(Constants.COMPONENT_TEARDOWN_WAIT); } @Test(timeout = 20000) public void inbox_singleMail_showsAllInboxDataCorrectly() throws Exception { try (JunitSocketClient client = new JunitSocketClient(mailboxConfig.getInt("dmtp.tcp.port"), err)) { err.checkThat("Expected mailbox server to implement DMTP2.0", client.read(), is("ok DMTP2.0")); client.sendAndVerify("begin", "ok"); client.sendAndVerify("from arthur@earth.planet", "ok"); client.sendAndVerify("to trillian@earth.planet", "ok"); client.sendAndVerify("subject somesubject", "ok"); client.sendAndVerify("data somedata", "ok"); client.sendAndVerify("hash 98yUrgHu4BctmhAel19nUAhGRVdVh9qD7Ge3VJBiehk=", "ok"); // valid hash client.sendAndVerify("send", "ok"); client.send("quit"); } Thread.sleep(2000); // wait a bit messageClientIn.addLine("inbox"); String output = messageClientOut.listen(); err.checkThat(output, allOf( containsString("trillian@earth.planet"), containsString("arthur@earth.planet"), containsString("somesubject"), containsString("somedata") )); } @Test(timeout = 20000) public void deletesMessage() throws Exception { try (JunitSocketClient client = new JunitSocketClient(mailboxConfig.getInt("dmtp.tcp.port"), err)) { err.checkThat("Expected mailbox server to implement DMTP2.0", client.read(), is("ok DMTP2.0")); client.sendAndVerify("begin", "ok"); client.sendAndVerify("from arthur@earth.planet", "ok"); client.sendAndVerify("to trillian@earth.planet", "ok"); client.sendAndVerify("subject somesubject", "ok"); client.sendAndVerify("data somedata", "ok"); client.sendAndVerify("hash 98yUrgHu4BctmhAel19nUAhGRVdVh9qD7Ge3VJBiehk=", "ok"); // valid hash client.sendAndVerify("send", "ok"); client.send("quit"); } Thread.sleep(2000); // wait a bit messageClientIn.addLine("delete 1"); assertThat(messageClientOut.listen(), containsString("ok")); } @Test(timeout = 5000) public void throwsErrorWhenTryingToDeleteNonexistentMessage() throws Exception { messageClientIn.addLine("delete 1"); assertThat(messageClientOut.listen(), containsString("there is no message with id 1")); } @Test(timeout = 40000) public void inbox_mulipleMails_showsAllInboxDataCorrectly() throws Exception { // send a mail to trillian try (JunitSocketClient client = new JunitSocketClient(mailboxConfig.getInt("dmtp.tcp.port"), err)) { err.checkThat("Expected mailbox server to implement DMTP2.0", client.read(), is("ok DMTP2.0")); client.sendAndVerify("begin", "ok"); client.sendAndVerify("from arthur@earth.planet", "ok"); client.sendAndVerify("to trillian@earth.planet", "ok"); client.sendAndVerify("subject somesubject", "ok"); client.sendAndVerify("data somedata", "ok"); client.sendAndVerify("hash 98yUrgHu4BctmhAel19nUAhGRVdVh9qD7Ge3VJBiehk=", "ok"); // valid hash client.sendAndVerify("send", "ok"); client.send("quit"); } // send another mail to trillian try (JunitSocketClient client = new JunitSocketClient(mailboxConfig.getInt("dmtp.tcp.port"), err)) { err.checkThat(client.read(), is("ok DMTP2.0")); client.sendAndVerify("begin", "ok"); client.sendAndVerify("from zaphod@univer.ze", "ok"); client.sendAndVerify("to trillian@earth.planet", "ok"); client.sendAndVerify("subject zaphodsubject", "ok"); client.sendAndVerify("data zaphoddata", "ok"); client.sendAndVerify("hash 4Bctm9nHuVU9qe3VJBhiAhGR987GyUekrgdVhhAel1D=", "ok"); // invalid hash client.sendAndVerify("send", "ok"); client.send("quit"); } // send a mail to arthur try (JunitSocketClient client = new JunitSocketClient(mailboxConfig.getInt("dmtp.tcp.port"), err)) { err.checkThat(client.read(), is("ok DMTP2.0")); client.sendAndVerify("begin", "ok"); client.sendAndVerify("from zaphod@univer.ze", "ok"); client.sendAndVerify("to arthur@earth.planet", "ok"); client.sendAndVerify("subject nottrilliansubject", "ok"); client.sendAndVerify("data nottrilliandata", "ok"); client.sendAndVerify("hash gdBctmhAeU9qel1DuV3VJBiUrhkA9Vhe4n987GyHhGR=", "ok"); // invalid hash client.sendAndVerify("send", "ok"); client.send("quit"); } Thread.sleep(2000); // wait a bit messageClientIn.addLine("inbox"); String output = messageClientOut.listen(3, TimeUnit.SECONDS); err.checkThat("inbox output did not contain all data from first mail", output, allOf( containsString("trillian@earth.planet"), containsString("arthur@earth.planet"), containsString("somesubject"), containsString("somedata") )); err.checkThat("inbox output did not contain all data from second mail", output, allOf( containsString("zaphod@univer.ze"), containsString("zaphodsubject"), containsString("zaphoddata") )); err.checkThat("inbox output contained data from a different user", output, not(anyOf( containsString("nottrilliansubject"), containsString("nottrilliandata") ))); } }