Package com.linkedin.databus.groupleader.impl.zkclient

Source Code of com.linkedin.databus.groupleader.impl.zkclient.TestLeaderElect

package com.linkedin.databus.groupleader.impl.zkclient;
/*
*
* Copyright 2013 LinkedIn Corp. 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.
*
*/


import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

import java.io.File;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.ZkServer;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import com.linkedin.databus.core.util.FileUtils;
import com.linkedin.databus.core.util.Utils;
import com.linkedin.databus.groupleader.pub.AcceptLeadershipCallback;
import com.linkedin.databus.groupleader.pub.GroupLeadershipConnection;
import com.linkedin.databus.groupleader.pub.GroupLeadershipConnectionFactory;
import com.linkedin.databus.groupleader.pub.GroupLeadershipSession;
import com.linkedin.databus2.test.TestUtil;

/*
* IMPORTANT NOTE : If you add any new test case methods, make sure you wrap it with LockObject.
* This class is NOT thread-safe without it but TestNg expects the test class to be thread-safe.
*/
public class TestLeaderElect
{
  private static final Logger LOG = Logger.getLogger(TestLeaderElect.class);

  public static final Object LockObject = new Object();

  public static String getRequiredStringProperty(String propname)
  {
    String val = System.getProperty(propname);

    if (val == null)
    {
      throw new IllegalArgumentException("Missing property: " + propname);
    }

    LOG.info("Property " + propname + "=" + val);
    return val;
  }

  public static int getRequiredIntProperty(String propname)
  {
    String stringVal = getRequiredStringProperty(propname);
    int intVal = Integer.parseInt(stringVal);
    return intVal;
  }

  public static boolean getRequiredBooleanProperty(String propname)
  {
    String stringVal = getRequiredStringProperty(propname);
    boolean booleanVal = Boolean.parseBoolean(stringVal);
    return booleanVal;
  }

  protected boolean _startLocalZookeeper;
  protected String _zkTestDataParentDir;
  protected String _zkTestDataRootDir;
  protected String _zkServerList;
  protected int _sessionTimeoutMillis;
  protected int _connectTimeoutMillis;
  protected int _zkServerTickTime = 2000;

  protected List<ZkServer> _localZkServers;
  protected GroupLeadershipConnectionFactory _groupLeadershipConnFactory;
  protected GroupLeadershipConnection _adminLeadershipConn;
  protected ZkClient _adminZkClient;

  @BeforeClass
  public void classSetup()
  {
    TestUtil.setupLoggingWithTimestampedFile(true, "/tmp/TestLeaderElect_", ".log",
                                             Level.INFO);
  }

  protected void setUp() throws Exception
  {
    //temporary

    System.setProperty("startLocalZookeeper","true");
    //.setProperty("zkServerList","localhost:2191,localhost:3192,localhost:4193");
    final int zkPort = Utils.getAvailablePort(2191);
        File zkroot = FileUtils.createTempDir("TestLeaderElect_zkroot");
        LOG.info("starting ZK on port " + zkPort + " and datadir " + zkroot.getAbsolutePath());

    System.setProperty("zkServerList","localhost:" + zkPort);

    System.setProperty("sessionTimeoutMillis","10000");
    System.setProperty("connectTimeoutMillis","5000");

    System.setProperty("zkTestDataParentDir", zkroot.getAbsolutePath());

    _startLocalZookeeper = getRequiredBooleanProperty("startLocalZookeeper");
    _zkTestDataParentDir = getRequiredStringProperty("zkTestDataParentDir");
    _zkServerList =  getRequiredStringProperty("zkServerList");
    _sessionTimeoutMillis = getRequiredIntProperty("sessionTimeoutMillis");
    _connectTimeoutMillis = getRequiredIntProperty("connectTimeoutMillis");


    if (_startLocalZookeeper)
    {
      _zkTestDataParentDir = _zkTestDataParentDir.trim();

      if (_zkTestDataParentDir.length() == 0)
      {
        throw new IllegalArgumentException("You must specify a valid zkTestDataParentDir when startLocalZookeeper=true");
      }

      File zkTestDataParentDirFile = new File(_zkTestDataParentDir);
      if (!zkTestDataParentDirFile.exists())
      {
        throw new IllegalArgumentException("Specified zkTestDataParentDir does not exist: " + _zkTestDataParentDir);
      }

      _zkTestDataRootDir = _zkTestDataParentDir + "/zkroot";

      List<Integer> localPortsList = LeaderElectUtils.parseLocalPorts(_zkServerList);


      if (localPortsList.size() > 1)
      {
        throw new IllegalArgumentException("Currently we only suppport starting ONE local zookeeper server");
      }

      _localZkServers = LeaderElectUtils.startLocalZookeeper(localPortsList, _zkTestDataRootDir, _zkServerTickTime);
    }

    _groupLeadershipConnFactory = new GroupLeadershipConnectionFactoryZkClientImpl(
        _zkServerList,
        _sessionTimeoutMillis,
        _connectTimeoutMillis);

    _adminLeadershipConn = _groupLeadershipConnFactory.getConnection();

    _adminZkClient = ((GroupLeadershipConnectionZkClientImpl) _adminLeadershipConn).getZkClient();

  }

    protected void tearDown() throws Exception
    {
      if (null != _adminLeadershipConn)
      {
        _adminLeadershipConn.close();
      }

      if (_startLocalZookeeper && null != _localZkServers)
      {
        LeaderElectUtils.stopLocalZookeeper(_localZkServers);
      }
    }

  protected String cleanZkGroupInfo(String zkBasePath, String groupName)
  {
    String groupNodePath = GroupLeadershipConnectionZkClientImpl.makeGroupNodePath(zkBasePath,groupName);
    _adminZkClient.deleteRecursive(groupNodePath);
    return groupNodePath;
  }

  /*
   * IMPORTANT NOTE : If you add any new test case methods, make sure you wrap it with LockObject.
   * This class is NOT thread-safe without it but TestNg expects the test class to be thread-safe.
   */
  @Test
  public void testLeaderElectSimple() throws Exception
  {
    synchronized(LockObject)
    {
      try
      {
        setUp();
        String baseName = "/databus2.testGroupLeader";
        String groupName = "TestLeaderElect.testLeaderElectSimple";
        cleanZkGroupInfo(baseName,groupName);

        final AtomicReference<String> callerMaintainedCurrentLeaderRef = new AtomicReference<String>();

        AcceptLeadershipCallback saveCurrentLeaderCallback =
            new AcceptLeadershipCallback()
        {
          @Override
          public void doAcceptLeadership(GroupLeadershipSession groupLeadershipSession)
          {
            callerMaintainedCurrentLeaderRef.set(groupLeadershipSession.getMemberName());
          }
        };

        GroupLeadershipConnection conn002 = _groupLeadershipConnFactory.getConnection();
        Assert.assertNull(conn002.getLeaderName(baseName,groupName),"Leader should be null");
        LOG.info("Group should not exist yet Test");
        assertFalse(conn002.getGroupNames(baseName).contains(groupName));

        GroupLeadershipSession sess002 = conn002.joinGroup(baseName,
            groupName, "002", saveCurrentLeaderCallback);

        assertEquals(groupName, sess002.getGroupName());
        assertEquals("002", sess002.getMemberName());
        assertEquals("002", (sess002.getLeaderName()));
        LOG.info("002 should be leader Test");
        assertFalse( ! sess002.isLeader());
        assertEquals("002", callerMaintainedCurrentLeaderRef.get());
        LOG.info("Group should exist Test");
        assertFalse(! conn002.getGroupNames(baseName).contains(groupName));
        assertEquals(groupName, conn002.getGroupLeadershipInfo(baseName,groupName).getGroupName());
        assertEquals("002", (conn002.getGroupLeadershipInfo(baseName,groupName).getLeaderName()));
        assertEquals(1, conn002.getGroupLeadershipInfo(baseName,groupName).getMemberNames().size());
        System.err.printf("membership info=%s\n", conn002.getGroupLeadershipInfo(baseName, groupName).getMemberNames());
        LOG.info("Member should be in group Test");
        assertFalse(!conn002.getGroupLeadershipInfo(baseName,groupName).getMemberNames().contains("002"));



        GroupLeadershipConnection conn001 = _groupLeadershipConnFactory.getConnection();

        GroupLeadershipSession sess001 = conn001.joinGroup(baseName,
            groupName, "001", saveCurrentLeaderCallback);

        assertEquals(groupName, sess001.getGroupName());
        assertEquals("001", sess001.getMemberName());
        assertEquals("002", (sess001.getLeaderName()));
        LOG.info("001 should not be leader");
        assertFalse(sess001.isLeader());
        assertEquals("002", callerMaintainedCurrentLeaderRef.get());

        LOG.info("Group should exist");
        assertFalse(! conn001.getGroupNames(baseName).contains(groupName));
        assertEquals(groupName, conn001.getGroupLeadershipInfo(baseName,groupName).getGroupName());
        assertEquals("002", (conn001.getGroupLeadershipInfo(baseName,groupName).getLeaderName()));
        assertEquals(2, conn001.getGroupLeadershipInfo(baseName,groupName).getMemberNames().size());
        LOG.info("Member should be in group");
        assertFalse(! conn001.getGroupLeadershipInfo(baseName,groupName).getMemberNames().contains("001"));
        LOG.info("Member should be in group");
        assertFalse(!conn001.getGroupLeadershipInfo(baseName,groupName).getMemberNames().contains("002"));



        GroupLeadershipConnection conn003 = _groupLeadershipConnFactory.getConnection();

        GroupLeadershipSession sess003 = conn003.joinGroup(baseName,
            groupName, "003", saveCurrentLeaderCallback);

        assertEquals(groupName, sess003.getGroupName());
        assertEquals("003", sess003.getMemberName());
        assertEquals("002", (sess003.getLeaderName()));
        LOG.info("003 should not be leader");
        assertFalse( sess003.isLeader());
        assertEquals("002", callerMaintainedCurrentLeaderRef.get());

        LOG.info("Group should exist");
        assertTrue(conn003.getGroupNames(baseName).contains(groupName));
        assertEquals(groupName, conn003.getGroupLeadershipInfo(baseName,groupName).getGroupName());
        assertEquals("002", (conn003.getGroupLeadershipInfo(baseName,groupName).getLeaderName()));
        assertEquals(3, conn003.getGroupLeadershipInfo(baseName,groupName).getMemberNames().size());
        LOG.info("Member should be in group");
        assertTrue(conn003.getGroupLeadershipInfo(baseName,groupName).getMemberNames().contains("001"));
        assertTrue(conn003.getGroupLeadershipInfo(baseName,groupName).getMemberNames().contains("002"));
        assertTrue(conn003.getGroupLeadershipInfo(baseName,groupName).getMemberNames().contains("003"));

        sess002.leaveGroup();

        for (int i = 0; i < 60; i++)
        {

          if ("001".equals((_adminLeadershipConn.getGroupLeadershipInfo(baseName,groupName).getLeaderName())))
          {
            break;
          }
          Thread.sleep(500);
        }

        assertEquals(groupName, sess001.getGroupName());
        assertEquals("001", sess001.getMemberName());
        assertEquals("001", (sess001.getLeaderName()));
        LOG.info("001 should be leader");
        assertTrue(sess001.isLeader());
        assertEquals("001", callerMaintainedCurrentLeaderRef.get());

        LOG.info("Group should exist");
        assertTrue(_adminLeadershipConn.getGroupNames(baseName).contains(groupName));
        assertEquals(groupName, _adminLeadershipConn.getGroupLeadershipInfo(baseName,groupName).getGroupName());
        assertEquals("001",(_adminLeadershipConn.getGroupLeadershipInfo(baseName,groupName).getLeaderName()));
        assertEquals(2, _adminLeadershipConn.getGroupLeadershipInfo(baseName,groupName).getMemberNames().size());
        LOG.info("Member should be in group");
        assertTrue(_adminLeadershipConn.getGroupLeadershipInfo(baseName,groupName).getMemberNames().contains("001"));
        assertTrue(_adminLeadershipConn.getGroupLeadershipInfo(baseName,groupName).getMemberNames().contains("003"));

        assertEquals(groupName, sess003.getGroupName());
        assertEquals("003", sess003.getMemberName());
        assertEquals("001", sess003.getLeaderName());
        LOG.info("003 should not be leader");
        assertFalse(sess003.isLeader());

        try
        {
          sess002.leaveGroup();
          fail("Should have gotten IllegalStateException");
        }
        catch (IllegalStateException e)
        {
          // expected
        }

        sess003.leaveGroup();
        sess001.leaveGroup();
        conn003.close();
        conn002.close();
        conn001.close();
      } finally {
        tearDown();
      }
    }
  }
}
TOP

Related Classes of com.linkedin.databus.groupleader.impl.zkclient.TestLeaderElect

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.