DS-Lab / src / test / java / dslab / IntegrationTest.java
IntegrationTest.java
Raw
package dslab;

import dslab.mailbox.IMailboxServer;
import dslab.mailbox.MailboxServer;
import dslab.transfer.ITransferServer;
import dslab.transfer.TransferServer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import static dslab.ComponentFactory.*;
import static dslab.Constants.COMPONENT_STARTUP_WAIT;
import static dslab.Sockets.waitForSocket;
import static dslab.TestObjects.trillianClient;
import static dslab.TestObjects.zaphodClient;
import static java.lang.Thread.sleep;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertThat;

public class IntegrationTest extends TestBase {

    private static final Logger LOG = Logger.getLogger(IntegrationTest.class.getSimpleName());

    private final TestInputStream rootNsIn = new TestInputStream();
    private final TestInputStream planetNsIn = new TestInputStream();
    private final TestInputStream earthPlanetMailboxServerIn = new TestInputStream();
    private final TestInputStream zeNsIn = new TestInputStream();
    private final TestInputStream univerZeMailboxServerIn = new TestInputStream();
    private final TestInputStream transferServerIn = new TestInputStream();
    private Map<String, Runnable> componentMap;


    @Before
    public void setup() throws Exception {
        //instantiate the components
        componentMap = Map.of(
                "rootNs", createNameserver("ns-root", rootNsIn, out),
                "planetNs", createNameserver("ns-planet", planetNsIn, out),
                "earthPlanetMailboxServer", createMailboxServer("mailbox-earth-planet", earthPlanetMailboxServerIn, out),
                "zeNs", createNameserver("ns-ze", zeNsIn, out),
                "univerZeMailboxServer", createMailboxServer("mailbox-univer-ze", univerZeMailboxServerIn, out),
                "transferServer", createTransferServer("transfer-1", transferServerIn, out)
        );

        //start them all
        componentMap.values().forEach(x -> new Thread(x).start());
    }

    @Test
    public void shouldReceiveMessage() throws Exception {

        var transferServer = (ITransferServer) componentMap.get("transferServer");
        var earthPlanetMailboxServer = (IMailboxServer) componentMap.get("earthPlanetMailboxServer");

        waitForSocket("localhost", dmtpPort(transferServer), COMPONENT_STARTUP_WAIT);

        //send a message
        try (JunitSocketClient client = new JunitSocketClient(dmtpPort(transferServer), null)) {
            client.verify("ok DMTP2.0");
            client.sendAndVerify("begin", "ok");
            client.sendAndVerify("from zaphod@univer.ze", "ok");
            client.sendAndVerify("to arthur@earth.planet", "ok 1");
            client.sendAndVerify("subject hello", "ok");
            client.sendAndVerify("data hello from junit", "ok");
            client.sendAndVerify("send", "ok");
            client.sendAndVerify("quit", "ok bye");
        }

        sleep(100); //give the transfer server time for delivery

        //check if it arrived
        try (JunitSocketClient client = new JunitSocketClient(dmapPort(earthPlanetMailboxServer), null)) {
            client.verify("ok DMAP2.0");
            client.sendAndVerify("login arthur 23456", "ok");
            client.sendAndVerify("list", List.of("1 zaphod@univer.ze hello", "ok"));
            client.sendAndVerify("quit", "ok bye");
        }
    }

    @Test
    public void shouldReceiveValidHash() throws Exception {

        //arrange
        var trillian = trillianClient();
        var zaphod = zaphodClient();

        //act
        trillian.in().addLine("msg zaphod@univer.ze,arthur@earth.planet lunch \"Let's have lunch!\"");
        sleep(5000); //give time for delivery
        zaphod.in().addLine("verify 1");

        //assert
        var listen = zaphod.out().listen();
        assertThat(listen, containsString("ok"));

        //cleanup
        trillian.close();
        zaphod.close();
    }

    @Test
    public void shouldReceiveDeliveryFailureReport() throws Exception {

        var transferServer = (ITransferServer) componentMap.get("transferServer");
        var earthPlanetMailboxServer = (IMailboxServer) componentMap.get("earthPlanetMailboxServer");

        waitForSocket("localhost", dmtpPort(transferServer), COMPONENT_STARTUP_WAIT);

        //send a message
        try (JunitSocketClient client = new JunitSocketClient(dmtpPort(transferServer), null)) {
            client.verify("ok DMTP2.0");
            client.sendAndVerify("begin", "ok");
            client.sendAndVerify("from arthur@earth.planet", "ok");
            client.sendAndVerify("to nonexistant@unknown.com", "ok 1");
            client.sendAndVerify("subject hello", "ok");
            client.sendAndVerify("data hello from junit", "ok");
            client.sendAndVerify("send", "ok");
            client.sendAndVerify("quit", "ok bye");
        }

        sleep(2000); //give the transfer server time for delivery

        //check if it arrived
        try (JunitSocketClient client = new JunitSocketClient(dmapPort(earthPlanetMailboxServer), null)) {
            client.verify("ok DMAP2.0");
            client.sendAndVerify("login arthur 23456", "ok");
            client.sendAndVerify("list", List.of("DELIVERY FAILURE", "ok"));
            client.sendAndVerify("quit", "ok bye");
        }
    }

    @After
    public void tearDown() throws Exception {
        rootNsIn.addLine("shutdown");
        planetNsIn.addLine("shutdown");
        earthPlanetMailboxServerIn.addLine("shutdown");
        zeNsIn.addLine("shutdown");
        univerZeMailboxServerIn.addLine("shutdown");
        transferServerIn.addLine("shutdown");

        Thread.sleep(Constants.COMPONENT_TEARDOWN_WAIT);
    }

    private int dmapPort(IMailboxServer mailboxServer) {
        return ((MailboxServer) mailboxServer).getComponentFactory().getConfig().getInt("dmap.tcp.port");
    }

    private int dmtpPort(ITransferServer transferServer) {
        return ((TransferServer) transferServer).getComponentFactory().getConfig().getInt("tcp.port");
    }
}