Package org.hive2hive.core.processes.implementations.common.base

Source Code of org.hive2hive.core.processes.implementations.common.base.BaseMessageProcessStepTest

package org.hive2hive.core.processes.implementations.common.base;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import java.io.IOException;
import java.security.PublicKey;
import java.util.List;
import java.util.Random;

import net.tomp2p.futures.FutureGet;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.rpc.ObjectDataReply;

import org.hive2hive.core.H2HJUnitTest;
import org.hive2hive.core.H2HTestData;
import org.hive2hive.core.H2HWaiter;
import org.hive2hive.core.exceptions.NoPeerConnectionException;
import org.hive2hive.core.exceptions.NoSessionException;
import org.hive2hive.core.exceptions.SendFailedException;
import org.hive2hive.core.network.NetworkManager;
import org.hive2hive.core.network.NetworkTestUtil;
import org.hive2hive.core.network.data.parameters.Parameters;
import org.hive2hive.core.network.messages.AcceptanceReply;
import org.hive2hive.core.network.messages.TestMessage;
import org.hive2hive.core.network.messages.TestMessageWithReply;
import org.hive2hive.core.network.messages.direct.response.ResponseMessage;
import org.hive2hive.core.processes.framework.exceptions.InvalidProcessStateException;
import org.hive2hive.core.processes.framework.exceptions.ProcessExecutionException;
import org.hive2hive.core.processes.util.TestProcessComponentListener;
import org.hive2hive.core.processes.util.UseCaseTestUtil;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

/**
* Tests for the {@link BaseMessageProcessStep} class. Checks if the process step successes when message
* successfully arrives and if the process step fails (triggers rollback) when the sending of a message fails.
*
* @author Seppi, Nico
*/
public class BaseMessageProcessStepTest extends H2HJUnitTest {

  private static List<NetworkManager> network;
  private static final int networkSize = 10;
  private static Random random = new Random();

  @BeforeClass
  public static void initTest() throws Exception {
    testClass = BaseMessageProcessStepTest.class;
    beforeClass();
    network = NetworkTestUtil.createNetwork(networkSize);
    NetworkTestUtil.createSameKeyPair(network);
  }

  /**
   * Sends an asynchronous message through a process step. This test checks if the process step successes
   * when the message arrives at the right target node (node which is responsible for the given key). This
   * is verified by locally storing and looking for the sent test data at the receiving node.
   *
   * @throws IOException
   * @throws ClassNotFoundException
   * @throws NoPeerConnectionException
   */
  @Test
  public void baseMessageProcessStepTestOnSuccess() throws ClassNotFoundException, IOException,
      NoPeerConnectionException {
    // select two random nodes
    NetworkManager nodeA = network.get(random.nextInt(network.size() / 2));
    final NetworkManager nodeB = network.get(random.nextInt(network.size() / 2) + network.size() / 2);
    // generate random data and content key
    String data = NetworkTestUtil.randomString();
    String contentKey = NetworkTestUtil.randomString();
    Parameters parameters = new Parameters().setLocationKey(nodeB.getNodeId()).setContentKey(contentKey);

    // check if selected location is empty
    FutureGet futureGet = nodeA.getDataManager().getUnblocked(parameters);
    futureGet.awaitUninterruptibly();
    assertNull(futureGet.getData());

    // create a message with target node B
    final TestMessage message = new TestMessage(nodeB.getNodeId(), contentKey, new H2HTestData(data));

    // initialize the process and the one and only step to test
    BaseMessageProcessStep step = new BaseMessageProcessStep(nodeA.getMessageManager()) {

      @Override
      protected void doExecute() throws InvalidProcessStateException {
        try {
          send(message, getPublicKey(nodeB));
        } catch (SendFailedException e) {
          Assert.fail(e.getMessage());
        }
      }

      @Override
      public void handleResponseMessage(ResponseMessage responseMessage) {
        Assert.fail("Should be not used.");
      }
    };
    UseCaseTestUtil.executeProcess(step);

    // wait till message gets handled
    H2HWaiter w = new H2HWaiter(10);
    do {
      w.tickASecond();
      futureGet = nodeA.getDataManager().getUnblocked(parameters);
      futureGet.awaitUninterruptibly();
    } while (futureGet.getData() == null);

    // verify that data arrived
    String result = ((H2HTestData) futureGet.getData().object()).getTestString();
    assertEquals(data, result);
  }

  /**
   * Sends an asynchronous message through a process step. This test checks if the process step fails
   * when the message gets denied at the target node (node which is responsible for the given key).
   *
   * @throws NoPeerConnectionException
   * @throws InvalidProcessStateException
   */
  @Test
  public void baseMessageProcessStepTestOnFailure() throws NoPeerConnectionException,
      InvalidProcessStateException {
    // select two random nodes
    NetworkManager nodeA = network.get(random.nextInt(network.size() / 2));
    final NetworkManager nodeB = network.remove(random.nextInt(network.size() / 2) + network.size() / 2);
    // generate random data and content key
    String data = NetworkTestUtil.randomString();
    String contentKey = NetworkTestUtil.randomString();
    Parameters parameters = new Parameters().setLocationKey(nodeB.getNodeId()).setContentKey(contentKey);

    // check if selected location is empty
    FutureGet futureGet = nodeA.getDataManager().getUnblocked(parameters);
    futureGet.awaitUninterruptibly();
    assertNull(futureGet.getData());

    // assign a denying message handler at target node
    nodeB.getConnection().getPeer().setObjectDataReply(new DenyingMessageReplyHandler());

    // create a message with target node B
    final TestMessage message = new TestMessage(nodeB.getNodeId(), contentKey, new H2HTestData(data));

    // initialize the process and the one and only step to test
    BaseMessageProcessStep step = new BaseMessageProcessStep(nodeA.getMessageManager()) {

      @Override
      protected void doExecute() throws InvalidProcessStateException, ProcessExecutionException {
        try {
          send(message, getPublicKey(nodeB));
          Assert.fail();
        } catch (SendFailedException e) {
          // expected
          throw new ProcessExecutionException("Expected behavior.", e);
        }
      }

      @Override
      public void handleResponseMessage(ResponseMessage responseMessage) {
        Assert.fail("Should be not used.");
      }
    };
    TestProcessComponentListener listener = new TestProcessComponentListener();
    step.attachListener(listener);
    step.start();
    // wait for the process to finish
    UseCaseTestUtil.waitTillFailed(listener, 10);

    // check if selected location is still empty
    futureGet = nodeA.getDataManager().getUnblocked(parameters);
    futureGet.awaitUninterruptibly();
    assertNull(futureGet.getData());
  }

  /**
   * Sends an asynchronous request message through a process step. This test checks if the process step
   * successes when receiving node responds to a request message.
   *
   * @throws IOException
   * @throws ClassNotFoundException
   * @throws NoPeerConnectionException
   */
  @Test
  public void baseMessageProcessStepTestWithARequestMessage() throws ClassNotFoundException, IOException,
      NoPeerConnectionException {
    // select two random nodes
    final NetworkManager nodeA = network.get(random.nextInt(network.size() / 2));
    final NetworkManager nodeB = network.get(random.nextInt(network.size() / 2) + network.size() / 2);
    // generate a random content key
    final String contentKey = NetworkTestUtil.randomString();
    final Parameters parametersA = new Parameters().setLocationKey(nodeA.getNodeId()).setContentKey(contentKey);
    final Parameters parametersB = new Parameters().setLocationKey(nodeB.getNodeId()).setContentKey(contentKey);
   
    // check if selected locations are empty
    FutureGet futureGet = nodeA.getDataManager().getUnblocked(parametersB);
    futureGet.awaitUninterruptibly();
    assertNull(futureGet.getData());
    futureGet = nodeB.getDataManager().getUnblocked(parametersA);
    futureGet.awaitUninterruptibly();
    assertNull(futureGet.getData());

    // create a message with target node B
    final TestMessageWithReply message = new TestMessageWithReply(nodeB.getNodeId(), contentKey);

    // initialize the process and the one and only step to test
    BaseMessageProcessStep step = new BaseMessageProcessStep(nodeA.getMessageManager()) {

      @Override
      protected void doExecute() throws InvalidProcessStateException {
        try {
          send(message, getPublicKey(nodeB));
        } catch (SendFailedException e) {
          Assert.fail(e.getMessage());
        }
      }

      @Override
      public void handleResponseMessage(ResponseMessage responseMessage) {
        // locally store on requesting node received data
        String receivedSecret = (String) responseMessage.getContent();
        try {
          nodeA.getDataManager().putUnblocked(parametersA.setData(new H2HTestData(receivedSecret)))
              .awaitUninterruptibly();
        } catch (NoPeerConnectionException e) {
          Assert.fail(e.getMessage());
        }
      }
    };
    UseCaseTestUtil.executeProcess(step);

    // wait till response message gets handled
    H2HWaiter waiter = new H2HWaiter(10);
    do {
      waiter.tickASecond();
      futureGet = nodeA.getDataManager().getUnblocked(parametersA);
      futureGet.awaitUninterruptibly();
    } while (futureGet.getData() == null);

    // load and verify if same secret was shared
    String receivedSecret = ((H2HTestData) futureGet.getData().object()).getTestString();
    futureGet = nodeA.getDataManager().getUnblocked(parametersB);
    futureGet.awaitUninterruptibly();
    String originalSecret = ((H2HTestData) futureGet.getData().object()).getTestString();

    assertEquals(originalSecret, receivedSecret);
  }

  private PublicKey getPublicKey(NetworkManager networkManager) {
    try {
      return networkManager.getSession().getKeyPair().getPublic();
    } catch (NoSessionException e) {
      return null;
    }
  }

  @AfterClass
  public static void endTest() {
    NetworkTestUtil.shutdownNetwork(network);
    afterClass();
  }

  private class DenyingMessageReplyHandler implements ObjectDataReply {
    @Override
    public Object reply(PeerAddress sender, Object request) throws Exception {
      return AcceptanceReply.FAILURE;
    }
  }
}
TOP

Related Classes of org.hive2hive.core.processes.implementations.common.base.BaseMessageProcessStepTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.