package com.cosylab.acs.maci.manager; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import junit.framework.TestCase; public class ProfilingReentrantLockTest extends TestCase { private ProfilingReentrantLock lock; protected void setUp() throws Exception { super.setUp(); lock = new ProfilingReentrantLock("Lock-" + getName()); System.out.println("\n------------ " + getName() + " --------------"); } protected void tearDown() throws Exception { super.tearDown(); } public void testCodeId() { assertEquals("Current line expected.", "ProfilingReentrantLockTest.java/23", lock.createCodeId(0)); assertEquals("Line from other method expected.", "ProfilingReentrantLockTest.java/32", createCodeIdWithExtraCallStackElement(0)); assertEquals("Current line expected.", "ProfilingReentrantLockTest.java/25", createCodeIdWithExtraCallStackElement(1)); } /** * This is part of {@link #testCodeId()}. */ private String createCodeIdWithExtraCallStackElement(int skipLevels) { return lock.createCodeId(skipLevels); } public void testSimple() throws Exception { System.out.println("About to acquire the lock."); lock.lock(); System.out.println("Acquired the lock."); try { Thread.sleep(100); } finally { lock.unlock(); System.out.println("Unlocked the lock."); } } /** * Acquires the lock from multiple threads, each of which then hold it for 100 ms. * The first thread should have acquiredMillis ~0, the other acquiredMillis ~ n * 100 ms. * All threads should have "heldMillis ~100". * This test is currently only useful for manual verification of the logged profiling data. */ public void testWithMultipleThreads() throws Exception { final int threadNumber = 5; final CountDownLatch sync = new CountDownLatch(threadNumber); Runnable r = new Runnable() { @Override public void run() { lock.lock(); try { try { Thread.sleep(100); } catch (InterruptedException ex) { ex.printStackTrace(); } } finally { lock.unlock(); sync.countDown(); } } }; for (int i = 0; i < threadNumber; i++) { (new Thread(r)).start(); // sleep a bit because otherwise the queue length best-effort output (from ReentrantLock#getQueueLength) // does not take the new thread into account. Thread.sleep(1); } sync.await(1, TimeUnit.SECONDS); } public void testNestedLocking() { final int nestingLevels = 5; for (int i = 0; i < nestingLevels; i++) { lock.lock(); } for (int i = 0; i < nestingLevels; i++) { lock.unlock(); } System.out.println("Nested locking/unlocking should have produced exactly one line of profiling output."); } }