/* * Copyright 2015-2016 OpenCB * * 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 org.opencb.opencga.storage.hadoop.utils; import org.apache.hadoop.hbase.io.compress.Compression; import org.apache.hadoop.hbase.util.Bytes; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.rules.ExternalResource; import org.opencb.opencga.storage.core.variant.VariantStorageBaseTest; import org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageTest; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * Created on 18/05/16 * * @author Jacobo Coll <jacobo167@gmail.com> */ public class HBaseLockTest extends VariantStorageBaseTest implements HadoopVariantStorageTest { @ClassRule public static ExternalResource externalResource = new HadoopExternalResource(); private HBaseLock hbaseLock; @BeforeClass public static void setUpClass() throws Exception { } @Before public void setUp() throws Exception { clearDB(DB_NAME); HBaseManager hbaseManager = new HBaseManager(configuration.get()); hbaseManager.createTableIfNeeded(DB_NAME, Bytes.toBytes("0"), Compression.Algorithm.NONE); hbaseLock = new HBaseLock(hbaseManager, DB_NAME, Bytes.toBytes("0"), Bytes.toBytes("R")); } @Test public void testLock() throws Exception { int lockId = 1; for (int i = 0; i < 10; i++) { System.out.println("i = " + i); long lock = hbaseLock.lock(getColumn(lockId), 10, 10); System.out.println("lock = " + lock); hbaseLock.unlock(getColumn(lockId), lock); } } @Test public void testConcurrentLock() throws Exception { int lockId = 2; AtomicInteger counter = new AtomicInteger(0); Set<String> threadWithLock = Collections.synchronizedSet(new HashSet<>()); int nThreads = 20; ExecutorService executorService = Executors.newFixedThreadPool(nThreads); List<Future> futures = new ArrayList<>(); for (int t = 0; t < nThreads; t++) { futures.add(executorService.submit(() -> { try { for (int i = 0; i < 5; i++) { System.out.println("i = " + i); long lock = hbaseLock.lock(getColumn(lockId), 1000, 20000); System.out.println("[" + Thread.currentThread().getName() + "] Enter LOCK"); assertEquals(threadWithLock.toString(), 0, threadWithLock.size()); threadWithLock.add(Thread.currentThread().getName()); assertEquals(threadWithLock.toString(), 1, threadWithLock.size()); int value = counter.addAndGet(1); Thread.sleep(100); assertEquals(threadWithLock.toString(), 1, threadWithLock.size()); assertEquals(threadWithLock.toString(), value, counter.get()); threadWithLock.remove(Thread.currentThread().getName()); System.out.println("lock = " + lock); System.out.println("[" + Thread.currentThread().getName() + "] Exit LOCK"); hbaseLock.unlock(getColumn(lockId), lock); } } catch (Exception e) { throw new RuntimeException(e); } })); } executorService.shutdown(); executorService.awaitTermination(2000, TimeUnit.SECONDS); for (Future future : futures) { assertTrue(future.isDone()); future.get(); } } public byte[] getColumn(int lockId) { return Bytes.toBytes(lockId); } @Test public void testLockAndLock() throws Exception { int lockId = 3; long lock = hbaseLock.lock(getColumn(lockId), 1000, 2000); System.out.println("lock = " + lock); thrown.expect(TimeoutException.class); hbaseLock.lock(getColumn(lockId), 1000, 1000); } @Test public void testLockAfterExpiring() throws Exception { int lockId = 4; long lock = hbaseLock.lock(getColumn(lockId), 1000, 1000); System.out.println("lock = " + lock); Thread.sleep(2000); System.out.println("Expired lock = " + lock); lock = hbaseLock.lock(getColumn(lockId), 1000, 1000); System.out.println("Unlock = " + lock); hbaseLock.unlock(getColumn(lockId), lock); } }