package com.workshare.msnos.integration; import com.workshare.msnos.core.*; import com.workshare.msnos.core.Message.Payload; import com.workshare.msnos.core.Message.Type; import com.workshare.msnos.integration.IntegrationActor.CommandPayload.Command; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; import java.util.UUID; import static com.workshare.msnos.integration.IntegrationActor.CommandPayload.Command.*; import static org.junit.Assert.assertTrue; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class CoreIT implements IntegrationActor { static { System.setProperty("com.ws.nsnos.time.local", "true"); } private static LocalAgent masterAgent; private static Cloud masterCloud; private static LocalAgent testAgent; private static Cloud testCloud; protected void sendCommand(final Command command) throws MsnosException { Payload data = CommandPayload.create(command); Message message = new MessageBuilder(Type.APP, masterAgent, masterCloud).with(data).make(); masterCloud.send(message); sleep(500l); } private static interface ConditionValidation { public boolean verified(); public String failure(); } private static enum Condition implements ConditionValidation { ONE_AGENT_IN_CLOUD { @Override public boolean verified() { return testCloud.getRemoteAgents().size() == 1; } @Override public String failure() { return testCloud.getRemoteAgents().size() + " found!"; } }, NO_AGENTS_IN_CLOUD { @Override public boolean verified() { return testCloud.getRemoteAgents().size() == 0; } @Override public String failure() { return testCloud.getRemoteAgents().size() + " found!"; } }; } @BeforeClass public static void bootstrap() throws MsnosException { System.setProperty("msnos.core.agents.timeout.millis", "1000"); masterAgent = new LocalAgent(UUID.randomUUID()); masterCloud = new Cloud(MASTER_CLOUD_UUID); masterAgent.join(masterCloud); testCloud = new Cloud(GENERIC_CLOUD_UUID); testAgent = new LocalAgent(UUID.randomUUID()); testAgent.join(testCloud); } @Before public void setup() throws Exception { sendCommand(INIT); } @After public void teardown() throws Exception { sendCommand(TERM); sendCommand(AGENT_LEAVE); waitForCondition(Condition.NO_AGENTS_IN_CLOUD); } @Test public void s01_shouldSeeRemoteJoining() throws Exception { sendCommand(AGENT_JOIN); assertCondition(Condition.ONE_AGENT_IN_CLOUD); } @Test public void s02_shouldUnseeRemoteLeaving() throws Exception { sendCommand(AGENT_JOIN); assertCondition(Condition.ONE_AGENT_IN_CLOUD); sendCommand(AGENT_LEAVE); assertCondition(Condition.NO_AGENTS_IN_CLOUD); } @Test public void s03_shouldUnseeRemoteDying() throws Exception { sendCommand(AGENT_JOIN); assertCondition(Condition.ONE_AGENT_IN_CLOUD); sendCommand(SELF_KILL); assertCondition(Condition.NO_AGENTS_IN_CLOUD); } private void assertCondition(final Condition condition) { assertTrue(condition.name()+": "+condition.failure(), waitForCondition(condition, 5000L)); } private boolean waitForCondition(ConditionValidation condition) { return waitForCondition(condition, 5000L); } private boolean waitForCondition(ConditionValidation condition, long timeout) { long end = System.currentTimeMillis() + timeout; while (System.currentTimeMillis() < end) { if (condition.verified()) return true; sleep(250L); } return false; } private void sleep(final long amount) { try { Thread.sleep(amount); } catch (InterruptedException e) { Thread.interrupted(); } } }