/* * Copyright (c) 2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.coordinator.client.service; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.apache.curator.framework.recipes.leader.LeaderSelector; import com.emc.storageos.coordinator.client.service.impl.LeaderSelectorListenerImpl; /** * LeaderSelector test is a set of routines to test validity of the leader selector framework */ public class LeaderSelectionTest extends CoordinatorTestBase { private static final Logger logger = LoggerFactory.getLogger(LeaderSelectionTest.class); public static final String LATCH_PATH = "leader_latch"; public static final String LATCH_NAME = "leader_processor"; final static int NUMCLIENTS = 2; final static int NUMRUN = 3; final static int DELAY = 1; // 1 sec delay final static int INTERVAL = 5; // 5 sec interval between jobs private static final ArrayList<String> leaderMonitor = new ArrayList(NUMCLIENTS * NUMRUN); private static final Lock monitorLock = new ReentrantLock(); private static final ArrayList<LeaderSelector> leaders = new ArrayList<LeaderSelector>(NUMCLIENTS); /** * Simulates multiple clients accessing persistent lock API simultaneously. * * @throws Exception */ @Test public void leaderSelectionTest() throws Exception { logger.info("*** Leader Seleciton Test start"); ExecutorService clients = Executors.newFixedThreadPool(NUMCLIENTS); for (int i = 0; i < NUMCLIENTS; i++) { final int count = i; clients.submit(new Runnable() { @Override public void run() { String leaderName = LATCH_NAME + '_' + (count + 1); LeaderSelector leader = null; try { TestProcessor processor = new TestProcessor(leaderName); leader = connectClient().getLeaderSelector(LATCH_PATH, processor); } catch (Exception e) { logger.info(": {} leaderSelectionTest could not get coordinator client", e); Assert.assertNull(e); return; } logger.info(": ### Initialized LeaderSelector {} ###", leaderName); leader.start(); leader.requeue(); synchronized (leaders) { leaders.add(leader); } } }); } synchronized (leaderMonitor) { while (leaderMonitor.size() < NUMCLIENTS * NUMRUN) { leaderMonitor.wait(); } } synchronized (leaders) { for (int i = 0; i < NUMCLIENTS; i++) { leaders.get(i).close(); } } synchronized (leaderMonitor) { for (int i = 0; i < NUMCLIENTS; i++) { for (int j = 0; j < NUMRUN; j++) { logger.info("Leadership : " + leaderMonitor.get(i * NUMRUN + j)); } String first = leaderMonitor.get(0).substring(0, 17); for (int j = 1; j < NUMRUN; j++) { Assert.assertTrue(leaderMonitor.get(j).startsWith(first)); } } } logger.info("*** LeaderSelector end"); } public static class TestProcessor extends LeaderSelectorListenerImpl { public String name; public TestProcessor(String name) { this.name = name; } protected void startLeadership() throws Exception { Thread.sleep(DELAY * 1000); for (int count = 0; count < NUMRUN; count++) { String message = name + '-' + (count + 1); synchronized (leaderMonitor) { leaderMonitor.add(message); leaderMonitor.notifyAll(); } logger.info("Adding message : " + message); Thread.sleep(INTERVAL * 1000); } } protected void stopLeadership() { } } }