/* * Copyright (c) 2008-2012 EMC Corporation * All Rights Reserved */ package com.emc.storageos.coordinator.client.service; import org.apache.curator.framework.recipes.locks.Lease; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * DistributedSemaphoreTest unit test */ public class DistributedSemaphoreTest extends CoordinatorTestBase { private static final Logger _logger = LoggerFactory.getLogger(DistributedSemaphoreTest.class); private static final String SEMAPHORE_NAME_TEST1 = "sampleSemClientTest1"; private final int POOLSIZE = 20; private ExecutorService _workers1 = Executors.newFixedThreadPool(POOLSIZE); private static final String SEMAPHORE_NAME_TEST2 = "sampleSemClientTest2"; private ExecutorService _workers2 = Executors.newFixedThreadPool(POOLSIZE); /** * Executes multiple workers using the semaphore (but acquiring with infinite wait). * If a worker is unable to acquire a lease, it blocks. * * @throws Exception */ @Test public void testDistributedSemaphore() throws Exception { final DistributedSemaphore mySem = connectClient().getSemaphore(SEMAPHORE_NAME_TEST1, 1); _logger.info("*** DistributedSemaphoreTest start"); for (int i = 0; i < POOLSIZE; i++) { _logger.info(": spawning worker number : " + i); _workers1.execute(new Runnable() { @Override public void run() { for (int i = 0; i < 25; i++) { _logger.info(": execution run number : " + i); Lease lease = null; Random rand = new Random(); try { _logger.info(": Going to acquire lease."); lease = mySem.acquireLease(); _logger.info(": Doing work holding lease : " + lease.toString()); } catch (Exception e) { _logger.info(": Problem when acquiring lease or doing work."); Assert.assertNull(e); } finally { if (lease != null) { _logger.info(": Work done .. going to return lease."); try { mySem.returnLease(lease); lease = null; Thread.sleep(rand.nextInt(500)); } catch (Exception e) { _logger.info(": Problem while returning lease: " + lease.toString()); Assert.assertNull(lease); } } else { _logger.info(": No lease to return."); } } } } }); } _workers1.shutdown(); Assert.assertTrue(_workers1.awaitTermination(60, TimeUnit.SECONDS)); _logger.info("*** DistributedSemaphoreTest end"); } /** * Executes multiple workers using the semaphore (but acquiring with finite wait). * If a worker is unable to acquire a lease within a specified time, it retries. * * @throws Exception */ @Test public void testDistributedSemaphoreFiniteWait() throws Exception { final DistributedSemaphore mySem = connectClient().getSemaphore(SEMAPHORE_NAME_TEST2, 1); _logger.info("*** DistributedSemaphoreFiniteWaitTest start"); for (int i = 0; i < POOLSIZE; i++) { _logger.info(": spawning worker number : " + i); _workers2.execute(new Runnable() { @Override public void run() { for (int i = 0; i < 25; i++) { _logger.info(": execution run number : " + i); Lease lease = null; Random rand = new Random(); try { _logger.info(": Going to acquire lease."); lease = mySem.acquireLease(50, TimeUnit.MILLISECONDS); if (lease == null) { _logger.info(": Could not acquire lease."); Thread.sleep(rand.nextInt(500)); } else { _logger.info(": Doing work holding lease : " + lease.toString()); } } catch (Exception e) { _logger.info(": Problem when acquiring lease or doing work."); Assert.assertNull(e); } finally { if (lease != null) { _logger.info(": Work done .. going to return lease."); try { mySem.returnLease(lease); lease = null; } catch (Exception e) { _logger.info(": Problem while returning lease: " + lease.toString()); Assert.assertNull(lease); } } else { _logger.info(": No lease to return."); } } } } }); } _workers2.shutdown(); Assert.assertTrue(_workers2.awaitTermination(60, TimeUnit.SECONDS)); _logger.info("*** DistributedSemaphoreFiniteWaitTest end"); } }