/* * Copyright (c) 2008-2012, Hazel Bilisim Ltd. 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. */ package com.hazelcast.client; import com.hazelcast.config.Config; import com.hazelcast.config.SemaphoreConfig; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.ISemaphore; import com.hazelcast.core.InstanceDestroyedException; import org.junit.*; import org.junit.runner.RunWith; import java.util.Random; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import static com.hazelcast.client.TestUtility.newHazelcastClient; import static junit.framework.Assert.fail; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @RunWith(com.hazelcast.util.RandomBlockJUnit4ClassRunner.class) public class HazelcastClientSemaphoreTest { @Before @After public void after() throws Exception { HazelcastClient.shutdownAll(); Hazelcast.shutdownAll(); } @BeforeClass @AfterClass public static void init() throws Exception { Hazelcast.shutdownAll(); } @Before public void setUp() throws Exception { Hazelcast.shutdownAll(); } @After public void tearDown() throws Exception { Hazelcast.shutdownAll(); } @Test public void testSemaphoreWithTimeout() { SemaphoreConfig semaphoreConfig = new SemaphoreConfig("test", 10); Config config = new Config(); config.addSemaphoreConfig(semaphoreConfig); HazelcastInstance instance = Hazelcast.newHazelcastInstance(config); HazelcastClient client = newHazelcastClient(instance); ISemaphore semaphore = client.getSemaphore("test"); //Test acquire and timeout. try { assertEquals(10, semaphore.availablePermits()); semaphore.tryAcquire(); assertEquals(9, semaphore.availablePermits()); assertEquals(false, semaphore.tryAcquire(10, 10, TimeUnit.MILLISECONDS)); assertEquals(9, semaphore.availablePermits()); semaphore.release(); //Test acquire and timeout and check for partial acquisitions. assertEquals(10, semaphore.availablePermits()); assertEquals(false, semaphore.tryAcquire(20, 10, TimeUnit.MILLISECONDS)); assertEquals(10, semaphore.availablePermits()); } catch (InterruptedException e) { fail(e.getMessage()); } catch (com.hazelcast.core.InstanceDestroyedException e) { e.printStackTrace(); } } @Test public void testSimpleSemaphore() { SemaphoreConfig semaphoreConfig = new SemaphoreConfig("test", 1); Config config = new Config(); config.addSemaphoreConfig(semaphoreConfig); HazelcastInstance instance = Hazelcast.newHazelcastInstance(config); HazelcastClient client = newHazelcastClient(instance); ISemaphore semaphore = client.getSemaphore("test"); assertEquals(1, semaphore.availablePermits()); semaphore.tryAcquire(); assertEquals(0, semaphore.availablePermits()); semaphore.release(); assertEquals(1, semaphore.availablePermits()); } @Test public void testSemaphoreReducePermits() { SemaphoreConfig semaphoreConfig = new SemaphoreConfig("test", 10); Config config = new Config(); config.addSemaphoreConfig(semaphoreConfig); HazelcastInstance instance = Hazelcast.newHazelcastInstance(config); HazelcastClient client = newHazelcastClient(instance); ISemaphore semaphore = client.getSemaphore("test"); assertEquals(10, semaphore.availablePermits()); semaphore.reducePermits(1); assertEquals(9, semaphore.availablePermits()); semaphore.tryAcquire(9); assertEquals(0, semaphore.availablePermits()); semaphore.reducePermits(8); assertEquals(-8, semaphore.availablePermits()); semaphore.release(); assertEquals(-7, semaphore.availablePermits()); semaphore.release(8); assertEquals(1, semaphore.availablePermits()); } @Test public void testSemaphoreDisconnect() throws InterruptedException { SemaphoreConfig semaphoreConfig = new SemaphoreConfig("default", 10); Config config = new Config(); config.addSemaphoreConfig(semaphoreConfig); HazelcastInstance instance = Hazelcast.newHazelcastInstance(config); HazelcastClient client1 = newHazelcastClient(instance); HazelcastClient client2 = newHazelcastClient(instance); ISemaphore semaphore1 = client1.getSemaphore("test"); ISemaphore semaphore2 = client2.getSemaphore("test"); assertEquals(10, semaphore1.availablePermits()); semaphore1.tryAcquireAttach(5); semaphore2.tryAcquire(3); semaphore1.reducePermits(1); assertEquals(1, semaphore2.availablePermits()); client1.shutdown(); assertEquals(6, semaphore2.availablePermits()); } @Test public void testSemaphorePeerDisconnect() { SemaphoreConfig semaphoreConfig = new SemaphoreConfig("default", 10); Config config = new Config(); config.addSemaphoreConfig(semaphoreConfig); HazelcastInstance instance = Hazelcast.newHazelcastInstance(config); HazelcastClient client1 = newHazelcastClient(instance); HazelcastClient client2 = newHazelcastClient(instance); ISemaphore semaphore1 = client1.getSemaphore("test"); ISemaphore semaphore2 = client2.getSemaphore("test"); semaphore2.tryAcquireAttach(5); semaphore2.tryAcquire(3); semaphore2.detach(2); assertEquals(2, semaphore1.availablePermits()); client2.shutdown(); assertEquals(5, semaphore1.availablePermits()); } @Test public void testSemaphoreIncreasePermits() { SemaphoreConfig semaphoreConfig = new SemaphoreConfig("default", 1); Config config = new Config(); config.addSemaphoreConfig(semaphoreConfig); HazelcastInstance instance = Hazelcast.newHazelcastInstance(config); HazelcastClient client = newHazelcastClient(instance); ISemaphore semaphore = client.getSemaphore("test"); assertEquals(1, semaphore.availablePermits()); semaphore.release(); assertEquals(2, semaphore.availablePermits()); } @Test public void testAsyncAcquire() throws Exception { HazelcastInstance instance = Hazelcast.newHazelcastInstance(null); HazelcastClient client = newHazelcastClient(instance); final ISemaphore semaphore = client.getSemaphore("test"); final Future f1 = semaphore.acquireAsync(); Thread thread = new Thread() { @Override public void run() { for (; ; ) { try { f1.get(); break; } catch (InterruptedException e) { // thread is interrupted but still trying to acquire assertTrue(f1.cancel(false)); semaphore.release(); break; } catch (ExecutionException e) { } } } }; thread.start(); Thread.sleep(1000); thread.interrupt(); thread.join(); assertEquals(1, semaphore.availablePermits()); } @Test public void testMultiInstanceSemaphore() { // three threads, two permits // thread 1: client acquire 2 permits 100 times // thread 2: client acquire 1 permits 200 times // thread 3: instance acquire 1 permits 300 times // test permit count never goes below zero and end count is same as start count final Random random = new Random(); final int rndTimeMax = 20; int initialPermits = 2; HazelcastInstance instance = Hazelcast.newHazelcastInstance(null); HazelcastClient client1 = newHazelcastClient(instance); HazelcastClient client2 = newHazelcastClient(instance); final ISemaphore semaphore1 = client1.getSemaphore("test"); final ISemaphore semaphore2 = client2.getSemaphore("test"); final ISemaphore semaphore3 = instance.getSemaphore("test"); semaphore1.release(initialPermits); assertEquals(initialPermits, semaphore1.availablePermits()); assertEquals(initialPermits, semaphore2.availablePermits()); assertEquals(initialPermits, semaphore3.availablePermits()); Thread thread1 = new Thread() { public void run() { for (int i = 0; i < 100; i++) { try { semaphore1.acquire(2); if (semaphore3.availablePermits() < 0) fail(); Thread.sleep(random.nextInt(rndTimeMax)); semaphore1.release(2); Thread.sleep(random.nextInt(rndTimeMax)); } catch (InterruptedException e) { fail(e.getMessage()); } catch (InstanceDestroyedException e) { fail(e.getMessage()); } } } }; Thread thread2 = new Thread() { public void run() { for (int i = 0; i < 200; i++) { try { semaphore2.acquire(); if (semaphore1.availablePermits() < 0) fail(); Thread.sleep(random.nextInt(rndTimeMax)); semaphore2.release(); Thread.sleep(random.nextInt(rndTimeMax)); } catch (InterruptedException e) { fail(e.getMessage()); } catch (InstanceDestroyedException e) { fail(e.getMessage()); } } } }; Thread thread3 = new Thread() { public void run() { for (int i = 0; i < 300; i++) { try { semaphore3.acquire(); if (semaphore2.availablePermits() < 0) fail(); Thread.sleep(random.nextInt(rndTimeMax)); semaphore3.release(); Thread.sleep(random.nextInt(rndTimeMax)); } catch (InterruptedException e) { fail(e.getMessage()); } catch (InstanceDestroyedException e) { fail(e.getMessage()); } } } }; thread1.start(); thread2.start(); thread3.start(); try { thread1.join(); thread2.join(); thread3.join(); } catch (InterruptedException e) { e.printStackTrace(); fail(); } assertEquals(initialPermits, semaphore1.availablePermits()); assertEquals(initialPermits, semaphore2.availablePermits()); assertEquals(initialPermits, semaphore3.availablePermits()); } }