All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.org.jgroups.protocols.JGroupsFailureDetectionJUnitTest Maven / Gradle / Ivy

There is a newer version: 2.0-BETA
Show newest version
/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You
 * may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License. See accompanying
 * LICENSE file.
 */
package com.gemstone.org.jgroups.protocols;

import java.io.Serializable;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;

import junit.framework.TestCase;

import com.gemstone.gemfire.internal.Assert;
import com.gemstone.org.jgroups.Address;
import com.gemstone.org.jgroups.ChannelClosedException;
import com.gemstone.org.jgroups.ChannelException;
import com.gemstone.org.jgroups.ChannelNotConnectedException;
import com.gemstone.org.jgroups.Event;
import com.gemstone.org.jgroups.JChannel;
import com.gemstone.org.jgroups.Message;
import com.gemstone.org.jgroups.SuspectMember;
import com.gemstone.org.jgroups.TimeoutException;
import com.gemstone.org.jgroups.View;
import com.gemstone.org.jgroups.ViewId;
import com.gemstone.org.jgroups.stack.IpAddress;
import com.gemstone.org.jgroups.stack.Protocol;
import com.gemstone.org.jgroups.stack.ProtocolStack;
import com.gemstone.org.jgroups.util.GemFireTracer;

public class JGroupsFailureDetectionJUnitTest extends TestCase {

  static final int numMembers = 40;
  static final int memberTimeout = 300;

  // JGroups protocol stacks for each member
  List stacks = new ArrayList(numMembers);

  // each member's address
  Vector members = new Vector(numMembers);
  
  // mapping from address to member's protocol stack
  Map addressToStack = new HashMap();
  

  
  
  public void setUp() throws Exception {
//    GemFireTracer.DEBUG = true;
    InetAddress addr = InetAddress.getLocalHost();

    // create the protocol stacks and addresses
    for (int i=1; i<=numMembers; i++) {
      IpAddress mbr = new IpAddress(addr, i+10000);
      members.add(mbr);
      ProtocolStack stack = createStack(mbr);
      stacks.add(stack);
      addressToStack.put(mbr, stack);
      getMessagingProtocol(stack).setRecipients(addressToStack);
    }
  }
  
  public void tearDown() throws Exception {
    GemFireTracer.DEBUG = false;
    for (ProtocolStack stack: stacks) {
      stack.stop();
    }
  }

  ProtocolStack createStack(IpAddress addr) throws Exception {
    CollectingProtocol top = new CollectingProtocol(true, false);
    TestFD_SOCK tfds = new TestFD_SOCK();
    TestFD tfd = new TestFD();
    TestVERIFY_SUSPECT tvs = new TestVERIFY_SUSPECT();
    MessagingProtocol bottom = new MessagingProtocol();
    
    // connect the protocols into a stack and start them
    top.setDownProtocol(tvs);
    tvs.setUpProtocol(top);  tvs.setDownProtocol(tfds);
    tfds.setUpProtocol(tvs); tfds.setDownProtocol(tfd);
    tfd.setUpProtocol(tfds); tfd.setDownProtocol(bottom);
//    tfdr.setUpProtocol(tfd); tfdr.setDownProtocol(bottom);
    bottom.setUpProtocol(tfd);
    
    MyChannel channel = MyChannel.create(null, addr);
    ProtocolStack stack = ProtocolStack.createTestStack(channel, top);
    Vector protocols = stack.getProtocols();
    for (int i=0; i
   * 
   * Forty stacks are created, simulating 40 members in a distributed system.
   * The first twenty are then killed and we observe how long it takes for the
   * remaining members to figure it out.  If they don't figure it out fast enough
   * the test fails.
   *  
   * @throws Exception
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public void testFailureDetectionManyMembers() throws Exception {
    
    
    // create the first view
    IpAddress coord = members.get(0);
    ViewId vid = new ViewId(coord, 1);
    View view = new View(vid, members);
    for (int i=0; i 0) {
            failures.append("\n");
          }
          failures.append("member ").append(i+1).append(" only saw ").append(numSuspects)
           .append(" failures but should have seen ").append(expectedCount).append(".  missing=");
          for (int si=0; si 0 && System.currentTimeMillis() < giveUpTime);
    if (failures.length() > 0) {
      Assert.fail(failures);
    } else {
      System.out.println("completed in "
          + (System.currentTimeMillis() - startTime) + "ms");
    }
  }
  
  
  public static class TestFD_SOCK extends FD_SOCK {
    public TestFD_SOCK() {
      num_tries=1;
      connectTimeout=memberTimeout;
      start_port=1024;
      end_port=65535;
      up_thread=false;
      down_thread=false;
    }
    public IpAddress getFdSockAddress() {
      return this.srv_sock_addr;
    }
    @Override
    public boolean isDisconnecting() {
      return !this.stack.getChannel().isConnected();
    }
  }
  
  public static class TestFD extends FD {
    public TestFD() {
      timeout=memberTimeout;
      max_tries=1;
      up_thread=false;
      down_thread=false;
      shun=false;
    }
  }
  
  public static class TestVERIFY_SUSPECT extends VERIFY_SUSPECT {
    public TestVERIFY_SUSPECT() {
      timeout=memberTimeout;
      up_thread=false;
      down_thread=false;
    }
  }
  
  public static class MessagingProtocol extends Protocol {
    Map recipients;
    IpAddress myAddress;
    
    public void setRecipients(Map recipients) {
      this.recipients = recipients;
    }
    public String getName() {
      return "MessagingProtocol";
    }
    public void up(Event ev) {
      switch (ev.getType()) {
      case Event.SET_LOCAL_ADDRESS:
        myAddress = (IpAddress)ev.getArg();
        break;
      }
      passUp(ev);
    }
    public void down(Event ev) {
      switch (ev.getType()) {
      case Event.MSG:
        Message m = (Message)ev.getArg();
        m.setSrc(myAddress);
        log.debug(""+myAddress+" is sending " + m);
        if (m.getDest() == null) {
          for (ProtocolStack stack: recipients.values()) {
            stack.getBottomProtocol().up(ev);
          }
        } else {
          ProtocolStack stack = recipients.get(m.getDest());
          if (stack.getChannel().isOpen()) {
            stack.getBottomProtocol().up(ev);
          }
        }
        break;
      default:
        passDown(ev);
      }
    }
  }

  /**
   * CollectingProtocol gathers the messages it receives in up() and down()
   * for later inspection.
   */
  public static class CollectingProtocol extends Protocol {
    List collectedUpEvents = null;
    List collectedDownEvents;
    Address myAddress;
    
    public CollectingProtocol(boolean collectUp, boolean collectDown) {
      if (collectUp) {
        collectedUpEvents = new LinkedList();
      }
      if (collectDown) {
        collectedDownEvents = new LinkedList();;
      }
    }
    
    @Override
    public String getName() {
      return "CollectingProtocol";
    }
    
    public void clear() {
      if (collectedDownEvents != null) {
        synchronized(collectedDownEvents) {
          collectedDownEvents.clear();
        }
      }
      if (collectedUpEvents != null) {
        synchronized(collectedUpEvents) {
          collectedUpEvents.clear();
        }
      }
    }
    
    @Override
    public void down(Event ev) {
      if (collectedDownEvents != null) {
        log.debug(""+myAddress+" collecting event " + ev);
        synchronized(collectedDownEvents) {
          collectedDownEvents.add(ev);
        }
      }
      passDown(ev);
    }
    
    @Override
    public void up(Event ev) {
      boolean skip = false;
      switch (ev.getType()) {
      case Event.SET_LOCAL_ADDRESS:
        myAddress = (IpAddress)ev.getArg();
        skip = true;
        break;
      case Event.MSG:
        skip = true;
        break;
      }
      if (!skip  &&  collectedUpEvents != null) {
        log.debug(""+myAddress+" collecting event " + ev);
        synchronized(collectedUpEvents) {
          collectedUpEvents.add(ev);
        }
      }
      passUp(ev);
    }
  }
  
  public static class MyChannel extends JChannel {

    boolean isOpen = true;
    View myView;
    Address myAddress;
    
    public static MyChannel create(View v, Address addr) throws ChannelException {
      MyChannel instance = new MyChannel();
      instance.myView = v;
      instance.myAddress = addr;
      return instance;
    }

    public void setProtocolStack(ProtocolStack stack) {
      this.prot_stack = stack;
    }

    public MyChannel() throws ChannelException {
    }
    
    public MyChannel(Properties p) throws ChannelException {
    }

    protected GemFireTracer getLog() {
      return null;
    }
    public void connect(String channel_name) throws ChannelException,
        ChannelClosedException {
    }
    public void disconnect() {
      isOpen = false;
    }
    public void close() {
      isOpen = false;
      getProtocolStack().down(new Event(Event.DISCONNECT));
      getProtocolStack().down(new Event(Event.STOP));
    }
    public void shutdown() {
      isOpen = false;
    }
    public boolean isOpen() {
      return isOpen;
    }
    public boolean isConnected() {
      return isOpen;
    }
    public Map dumpStats() {
      return null;
    }
    public void send(Message msg) throws ChannelNotConnectedException,
        ChannelClosedException {
    }
    public void send(Address dst, Address src, Serializable obj)
        throws ChannelNotConnectedException, ChannelClosedException {
    }
    public Object receive(long timeout) throws ChannelNotConnectedException,
        ChannelClosedException, TimeoutException {
      return null;
    }
    public Object peek(long timeout) throws ChannelNotConnectedException,
        ChannelClosedException, TimeoutException {
      return null;
    }
    public View getView() {
      return myView;
    }
    public Address getLocalAddress() {
      return myAddress;
    }
    public String getChannelName() {
      return "GF7";
    }
    public void setOpt(int option, Object value) {
    }
    public Object getOpt(int option) {
      return null;
    }
    public void blockOk() {
    }
    public boolean getState(Address target, long timeout)
        throws ChannelNotConnectedException, ChannelClosedException {
      return false;
    }
    public boolean closing() {
      return !isOpen;
    }
    public boolean getAllStates(Vector targets, long timeout)
        throws ChannelNotConnectedException, ChannelClosedException {
      return false;
    }
    public void returnState(byte[] state) {
    }
    
  }
  
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy