Package net.sf.katta.protocol

Source Code of net.sf.katta.protocol.InteractionProtocolTest

/**
* Copyright 2008 the original author or authors.
*
* 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.
*/
package net.sf.katta.protocol;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import net.sf.katta.AbstractZkTest;
import net.sf.katta.master.Master;
import net.sf.katta.node.Node;
import net.sf.katta.node.monitor.MetricsRecord;
import net.sf.katta.operation.OperationId;
import net.sf.katta.operation.master.AbstractIndexOperation;
import net.sf.katta.operation.master.MasterOperation;
import net.sf.katta.operation.node.NodeOperation;
import net.sf.katta.protocol.metadata.IndexMetaData;
import net.sf.katta.protocol.metadata.NodeMetaData;
import net.sf.katta.protocol.metadata.IndexMetaData.Shard;
import net.sf.katta.testutil.Mocks;
import net.sf.katta.testutil.mockito.WaitingAnswer;
import net.sf.katta.util.ZkConfiguration.PathDef;

import org.I0Itec.zkclient.Gateway;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.util.ZkPathUtil;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.proto.WatcherEvent;
import org.junit.Test;
import org.mockito.InOrder;

public class InteractionProtocolTest extends AbstractZkTest {

  @Test(timeout = 7000)
  public void testLifecycle() throws Exception {
    int GATEWAY_PORT = 2190;
    Gateway gateway = new Gateway(GATEWAY_PORT, _zk.getServerPort());
    gateway.start();
    ZkClient zkClient = new ZkClient("localhost:" + GATEWAY_PORT);

    InteractionProtocol protocol = new InteractionProtocol(zkClient, _zk.getZkConf());
    final AtomicInteger connectCount = new AtomicInteger();
    final AtomicInteger disconnectCount = new AtomicInteger();
    final Object mutex = new Object();

    protocol.registerComponent(new ConnectedComponent() {
      @Override
      public void disconnect() {
        disconnectCount.incrementAndGet();
        synchronized (mutex) {
          mutex.notifyAll();
        }
      }

      @Override
      public void reconnect() {
        connectCount.incrementAndGet();
        synchronized (mutex) {
          mutex.notifyAll();
        }
      }
    });
    synchronized (mutex) {
      gateway.stop();
      mutex.wait();
      gateway.start();
      mutex.wait();
      gateway.stop();
      mutex.wait();
      gateway.start();
      mutex.wait();
    }
    zkClient.close();
    assertEquals(2, connectCount.get());
    assertEquals(2, connectCount.get());
    gateway.stop();
  }

  @Test(timeout = 7000)
  public void testNodeQueue() throws Exception {
    Node node = mock(Node.class);
    String nodeName = "node1";
    when(node.getName()).thenReturn(nodeName);

    InteractionProtocol protocol = _zk.getInteractionProtocol();
    NodeQueue nodeQueue = protocol.publishNode(node, new NodeMetaData());

    NodeOperation nodeOperation1 = mock(NodeOperation.class, withSettings().serializable().name("a"));
    NodeOperation nodeOperation2 = mock(NodeOperation.class, withSettings().serializable().name("b"));
    OperationId operation1Id = protocol.addNodeOperation(nodeName, nodeOperation1);
    OperationId operation2Id = protocol.addNodeOperation(nodeName, nodeOperation2);

    assertTrue(protocol.isNodeOperationQueued(operation1Id));
    assertTrue(protocol.isNodeOperationQueued(operation2Id));
    assertEquals(nodeOperation1.toString(), nodeQueue.remove().toString());
    assertEquals(nodeOperation2.toString(), nodeQueue.remove().toString());
    assertTrue(nodeQueue.isEmpty());
    assertFalse(protocol.isNodeOperationQueued(operation1Id));
    assertFalse(protocol.isNodeOperationQueued(operation2Id));
  }

  @Test(timeout = 7000)
  public void testPublishMaster() throws Exception {
    Master master1 = mock(Master.class);
    Master master2 = mock(Master.class);
    when(master1.getMasterName()).thenReturn("master1");
    when(master2.getMasterName()).thenReturn("master2");
    MasterOperation operation = mock(MasterOperation.class);
    _protocol.addMasterOperation(operation);

    MasterQueue queue = _protocol.publishMaster(master1);
    assertNotNull(queue);
    assertNotNull(_protocol.getMasterMD());
    assertEquals(1, queue.size());
    assertNotNull(queue.peek());

    // same again
    queue = _protocol.publishMaster(master1);
    assertNotNull(queue);
    assertNotNull(_protocol.getMasterMD());

    // second master
    queue = _protocol.publishMaster(master2);
    assertNull(queue);
    assertNotNull(_protocol.getMasterMD());
  }

  @Test(timeout = 7000)
  public void testPublishNode() throws Exception {
    Node node = Mocks.mockNode();
    assertNull(_protocol.getNodeMD(node.getName()));
    NodeQueue queue = _protocol.publishNode(node, new NodeMetaData(node.getName()));
    assertNotNull(queue);
    assertNotNull(_protocol.getNodeMD(node.getName()));

    // test operation
    NodeOperation operation = mock(NodeOperation.class);
    OperationId operationId = _protocol.addNodeOperation(node.getName(), operation);
    assertEquals(1, queue.size());
    assertNotNull(queue.peek());
    assertEquals(node.getName(), operationId.getNodeName());
  }

  @Test(timeout = 7000)
  public void testExplainStructure() throws Exception {
    _protocol.explainStructure();
    System.out.println("----------------");
    _protocol.showStructure(false);
    System.out.println("----------------");
    _protocol.showStructure(true);
  }

  @Test(timeout = 7000)
  public void testUnregisterListenersOnUnregisterComponent() throws Exception {
    ConnectedComponent component = mock(ConnectedComponent.class);
    _protocol.registerComponent(component);

    IAddRemoveListener childListener = mock(IAddRemoveListener.class);
    IZkDataListener dataListener = mock(IZkDataListener.class);
    _protocol.registerChildListener(component, PathDef.NODES_LIVE, childListener);
    _protocol.registerDataListener(component, PathDef.NODES_LIVE, "node1", dataListener);

    _zk.getZkClient().createPersistent(_zk.getZkConf().getZkPath(PathDef.NODES_LIVE, "node1"));
    Thread.sleep(500);
    verify(childListener).added("node1");
    verify(dataListener).handleDataChange(anyString(), any());
    verifyNoMoreInteractions(childListener, dataListener);

    _protocol.unregisterComponent(component);
    _zk.getZkClient().delete(_zk.getZkConf().getZkPath(PathDef.NODES_LIVE, "node1"));
    Thread.sleep(500);
    verifyNoMoreInteractions(childListener, dataListener);
    // ephemerals should be removed
    // listeners nshould be removed
  }

  @Test(timeout = 7000)
  public void testDeleteEphemeraksOnUnregisterComponent() throws Exception {
    Master master = mock(Master.class);
    _protocol.publishMaster(master);
    assertNotNull(_protocol.getMasterMD());

    _protocol.unregisterComponent(master);
    assertNull(_protocol.getMasterMD());
  }

  @Test(timeout = 7000)
  public void testChildListener() throws Exception {
    ConnectedComponent component = mock(ConnectedComponent.class);
    IAddRemoveListener listener = mock(IAddRemoveListener.class);
    PathDef pathDef = PathDef.NODES_LIVE;

    _zk.getZkClient().createPersistent(_zk.getZkConf().getZkPath(pathDef, "node1"));
    List<String> existingChilds = _protocol.registerChildListener(component, pathDef, listener);
    assertEquals(1, existingChilds.size());
    assertTrue(existingChilds.contains("node1"));

    _zk.getZkClient().createPersistent(_zk.getZkConf().getZkPath(pathDef, "node2"));
    _zk.getZkClient().delete(_zk.getZkConf().getZkPath(pathDef, "node1"));

    Thread.sleep(500);
    InOrder inOrder = inOrder(listener);
    inOrder.verify(listener).added("node2");
    inOrder.verify(listener).removed("node1");
    verifyNoMoreInteractions(listener);
  }

  @Test(timeout = 70000)
  public void testDataListener() throws Exception {
    ConnectedComponent component = mock(ConnectedComponent.class);
    IZkDataListener listener = mock(IZkDataListener.class);
    PathDef pathDef = PathDef.INDICES_METADATA;
    String zkPath = _zk.getZkConf().getZkPath(pathDef, "index1");

    Long serializable = new Long(1);
    _zk.getZkClient().createPersistent(zkPath, serializable);
    _protocol.registerDataListener(component, pathDef, "index1", listener);

    serializable = new Long(2);
    _zk.getZkClient().writeData(zkPath, serializable);
    Thread.sleep(500);
    verify(listener).handleDataChange(zkPath, serializable);

    _zk.getZkClient().delete(zkPath);
    Thread.sleep(500);
    verify(listener).handleDataDeleted(zkPath);
    verifyNoMoreInteractions(listener);
  }

  @Test(timeout = 70000)
  public void testIndexManagement() throws Exception {
    IndexMetaData indexMD = new IndexMetaData("index1", "indexPath", 2);
    indexMD.getShards().add(new Shard(AbstractIndexOperation.createShardName(indexMD.getName(), "path1"), "path1"));
    Node node = Mocks.mockNode();

    assertNull(_protocol.getIndexMD("index1"));
    assertEquals(0, _protocol.getIndices().size());

    // publish index
    _protocol.publishIndex(indexMD);
    _protocol.publishShard(node, indexMD.getShards().iterator().next().getName());
    assertNotNull(_protocol.getIndexMD("index1"));
    assertEquals(1, _protocol.getIndices().size());
    assertEquals(indexMD.getReplicationLevel(), _protocol.getIndexMD(indexMD.getName()).getReplicationLevel());

    // update index
    indexMD.setReplicationLevel(3);
    _protocol.updateIndexMD(indexMD);
    assertEquals(indexMD.getReplicationLevel(), _protocol.getIndexMD(indexMD.getName()).getReplicationLevel());

    _protocol.showStructure(false);
    _protocol.unpublishIndex(indexMD.getName());
    _protocol.showStructure(false);
    assertNull(_protocol.getIndexMD("index1"));
    assertEquals(0, _protocol.getIndices().size());

    String string = ZkPathUtil.toString(_protocol._zkClient);
    Set<Shard> shards = indexMD.getShards();
    for (Shard shard : shards) {
      assertFalse(string.contains(shard.getName()));
    }
  }

  @Test(timeout = 7000)
  public void testShardManagement() throws Exception {
    Node node1 = Mocks.mockNode();
    Node node2 = Mocks.mockNode();
    Map<String, String> shardMD = new HashMap<String, String>();
    shardMD.put("a", "1");

    assertEquals(0, _protocol.getShardNodes("shard1").size());

    // publish shard
    _protocol.publishShard(node1, "shard1");
    assertEquals(1, _protocol.getShardNodes("shard1").size());
    assertEquals(1, _protocol.getNodeShards(node1.getName()).size());
    assertEquals(0, _protocol.getNodeShards(node2.getName()).size());

    // publish shard on 2nd node
    _protocol.publishShard(node2, "shard1");
    assertEquals(2, _protocol.getShardNodes("shard1").size());
    assertEquals(1, _protocol.getNodeShards(node1.getName()).size());
    assertEquals(1, _protocol.getNodeShards(node2.getName()).size());

    // remove shard on first node
    _protocol.unpublishShard(node1, "shard1");
    assertEquals(1, _protocol.getShardNodes("shard1").size());
    assertEquals(0, _protocol.getNodeShards(node1.getName()).size());
    assertEquals(1, _protocol.getNodeShards(node2.getName()).size());

    // publish 2nd shard
    _protocol.publishShard(node1, "shard2");
    assertEquals(1, _protocol.getShardNodes("shard1").size());
    assertEquals(1, _protocol.getShardNodes("shard2").size());
    assertEquals(1, _protocol.getNodeShards(node1.getName()).size());
    assertEquals(1, _protocol.getNodeShards(node2.getName()).size());

    // remove one shard completely
    _protocol.unpublishShard(node1, "shard2");

    Map<String, List<String>> shard2NodesMap = _protocol.getShard2NodesMap(Arrays.asList("shard1"));
    assertEquals(1, shard2NodesMap.size());
    assertEquals(1, shard2NodesMap.get("shard1").size());
  }

  @Test(timeout = 7000)
  public void testMetrics() throws Exception {
    String nodeName1 = "node1";
    assertNull(_protocol.getMetric(nodeName1));
    _protocol.setMetric(nodeName1, new MetricsRecord(nodeName1));
    assertNotNull(_protocol.getMetric(nodeName1));

    String nodeName2 = "node2";
    _protocol.setMetric(nodeName2, new MetricsRecord(nodeName1));
    assertNotSame(_protocol.getMetric(nodeName1).getServerId(), _protocol.getMetric(nodeName2).getServerId());
  }

  @Test
  /**see KATTA-125*/
  public void testConcurrentModification() throws Exception {
    ConnectedComponent component1 = mock(ConnectedComponent.class);
    WaitingAnswer waitingAnswer = new WaitingAnswer();
    doAnswer(waitingAnswer).when(component1).disconnect();
    _protocol = _zk.createInteractionProtocol();
    _protocol.registerComponent(component1);
    WatchedEvent expiredEvent = new WatchedEvent(new WatcherEvent(EventType.None.getIntValue(), KeeperState.Expired
            .getIntValue(), null));
    _protocol.getZkClient().process(
            new WatchedEvent(new WatcherEvent(EventType.None.getIntValue(), KeeperState.SyncConnected.getIntValue(),
                    null)));
    _protocol.getZkClient().process(expiredEvent);
    // verify(component1).disconnect();

    ConnectedComponent component2 = mock(ConnectedComponent.class, "2ndComp");
    _protocol.registerComponent(component2);
    _protocol.unregisterComponent(component2);
    waitingAnswer.release();
    _protocol.disconnect();
  }
}
TOP

Related Classes of net.sf.katta.protocol.InteractionProtocolTest

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.