2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.openflowplugin.applications.frsync.util;
11 import java.util.concurrent.ConcurrentHashMap;
12 import java.util.concurrent.ConcurrentMap;
13 import java.util.concurrent.ExecutorService;
14 import java.util.concurrent.LinkedBlockingQueue;
15 import java.util.concurrent.Semaphore;
16 import java.util.concurrent.ThreadPoolExecutor;
17 import java.util.concurrent.TimeUnit;
19 import org.junit.Assert;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.opendaylight.openflowplugin.applications.frsync.SemaphoreKeeper;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
27 * Test for {@link SemaphoreKeeperGuavaImpl}.
29 public class SemaphoreKeeperTest {
30 private static final Logger LOG = LoggerFactory.getLogger(SemaphoreKeeperTest.class);
31 private SemaphoreKeeperGuavaImpl<String> semaphoreKeeper;
32 final String key = "11";
35 public void setUp() throws Exception {
36 semaphoreKeeper = new SemaphoreKeeperGuavaImpl(1, true);
40 public void testSummonGuard() throws Exception {
41 Semaphore semaphore1 = semaphoreKeeper.summonGuard(key);
42 final int g1FingerPrint = semaphore1.hashCode();
43 Semaphore semaphore2 = semaphoreKeeper.summonGuard(key);
44 final int g2FingerPrint = semaphore2.hashCode();
46 Assert.assertSame(semaphore1, semaphore2);
47 Assert.assertEquals(1, semaphore1.availablePermits());
51 Assert.assertEquals(1, semaphore1.availablePermits());
57 Assert.assertEquals(1, semaphore2.availablePermits());
59 Assert.assertEquals(g1FingerPrint, g2FingerPrint);
62 final Semaphore semaphore3 = semaphoreKeeper.summonGuard(key);
63 Assert.assertNotEquals(g1FingerPrint, semaphore3.hashCode());
67 public void testReleaseGuard() throws Exception {
68 for (int total = 1; total <= 10; total++) {
69 LOG.info("test run: {}", total);
70 final Worker task = new Worker(semaphoreKeeper, key);
72 final ExecutorService executorService = new ThreadPoolExecutor(5, 5,
73 0L, TimeUnit.MILLISECONDS,
74 new LinkedBlockingQueue<Runnable>()) {
76 protected void afterExecute(final Runnable r, final Throwable t) {
77 super.afterExecute(r, t);
79 LOG.error("pool thread crashed", t);
85 for (int i = 0; i < steps; i++) {
86 executorService.submit(task);
89 LOG.info("STARTING new serie");
92 for (int i = 0; i < steps; i++) {
93 executorService.submit(task);
98 executorService.shutdown();
99 final boolean terminated = executorService.awaitTermination(10, TimeUnit.SECONDS);
101 LOG.warn("pool stuck, forcing termination");
102 executorService.shutdownNow();
103 Assert.fail("pool failed to finish gracefully");
106 final int counterSize = task.getCounterSize();
107 LOG.info("final counter = {}", counterSize);
108 Assert.assertEquals(20, counterSize);
112 private static class Worker implements Runnable {
113 private final SemaphoreKeeper<String> keeper;
114 private final String key;
115 private ConcurrentMap<Integer, Integer> counter = new ConcurrentHashMap<>();
116 private volatile int index = 0;
118 public Worker(SemaphoreKeeper<String> keeper, final String key) {
119 this.keeper = keeper;
126 final Semaphore guard = keeper.summonGuard(key);
129 counter.putIfAbsent(index, 0);
130 counter.put(index, counter.get(index) + 1);
131 LOG.debug("queue: {} [{}] - {}", guard.getQueueLength(), guard.hashCode(), counter.size());
134 } catch (Exception e) {
135 LOG.warn("acquiring failed.. ", e);
139 public int getCounterSize() {
140 return counter.size();