1   package com.atlassian.util.concurrent;
2   
3   import static com.atlassian.util.concurrent.ManagedLocks.manage;
4   import static junit.framework.Assert.fail;
5   import static org.junit.Assert.assertEquals;
6   import static org.junit.Assert.assertTrue;
7   
8   import java.util.concurrent.Callable;
9   import java.util.concurrent.atomic.AtomicBoolean;
10  import java.util.concurrent.locks.ReentrantLock;
11  
12  import org.junit.Test;
13  
14  public class ManagedLockTest {
15      @Test
16      public void supplierReturnsValue() throws Exception {
17          final AtomicBoolean called = new AtomicBoolean();
18          assertEquals("blah", manage(new ReentrantLock()).withLock(new Supplier<String>() {
19              public String get() {
20                  called.set(true);
21                  return "blah";
22              }
23          }));
24          assertTrue(called.get());
25      }
26  
27      @Test
28      public void callableReturnsValue() throws Exception {
29          final AtomicBoolean called = new AtomicBoolean();
30          assertEquals("blah", manage(new ReentrantLock()).withLock(new Callable<String>() {
31              public String call() {
32                  called.set(true);
33                  return "blah";
34              }
35          }));
36          assertTrue(called.get());
37      }
38  
39      @Test
40      public void runnableRuns() throws Exception {
41          final AtomicBoolean called = new AtomicBoolean();
42          manage(new ReentrantLock()).withLock(new Runnable() {
43              public void run() {
44                  called.set(true);
45              }
46          });
47          assertTrue(called.get());
48      }
49  
50      @Test
51      public void locksAndUnlocksAndThrows() throws Exception {
52          final AtomicBoolean called = new AtomicBoolean();
53          final AtomicBoolean locked = new AtomicBoolean();
54          final AtomicBoolean unlocked = new AtomicBoolean();
55          final ManagedLock manager = new ManagedLocks.ManagedLockImpl(new ReentrantLock() {
56              private static final long serialVersionUID = 5047219203514192915L;
57  
58              @Override
59              public void lock() {
60                  locked.set(true);
61                  super.lock();
62              }
63  
64              @Override
65              public void unlock() {
66                  unlocked.set(true);
67                  super.unlock();
68              }
69          });
70  
71          class StupidException extends Exception {
72              private static final long serialVersionUID = -885206738173390512L;
73          }
74  
75          try {
76              manager.withLock(new Callable<String>() {
77                  public String call() throws StupidException {
78                      called.set(true);
79                      throw new StupidException();
80                  }
81              });
82          } catch (final StupidException ignore) {}
83  
84          assertTrue(called.get());
85          assertTrue(locked.get());
86          assertTrue(unlocked.get());
87      }
88  
89      @Test
90      public void locksAndUnlocksAndRuns() throws Exception {
91          final AtomicBoolean called = new AtomicBoolean();
92          final AtomicBoolean locked = new AtomicBoolean();
93          final AtomicBoolean unlocked = new AtomicBoolean();
94          final ManagedLock manager = new ManagedLocks.ManagedLockImpl(new ReentrantLock() {
95              private static final long serialVersionUID = -5545182312276280121L;
96  
97              @Override
98              public void lock() {
99                  locked.set(true);
100                 super.lock();
101             }
102 
103             @Override
104             public void unlock() {
105                 unlocked.set(true);
106                 super.unlock();
107             }
108         });
109 
110         manager.withLock(new Runnable() {
111             public void run() {
112                 called.set(true);
113             }
114         });
115 
116         assertTrue(called.get());
117         assertTrue(locked.get());
118         assertTrue(unlocked.get());
119     }
120 
121     @Test
122     public void locksAndUnlocksAndThrowsRuntime() throws Exception {
123         final AtomicBoolean called = new AtomicBoolean();
124         final AtomicBoolean locked = new AtomicBoolean();
125         final AtomicBoolean unlocked = new AtomicBoolean();
126         final ManagedLock manager = new ManagedLocks.ManagedLockImpl(new ReentrantLock() {
127             private static final long serialVersionUID = 4219143544310279745L;
128 
129             @Override
130             public void lock() {
131                 locked.set(true);
132                 super.lock();
133             }
134 
135             @Override
136             public void unlock() {
137                 unlocked.set(true);
138                 super.unlock();
139             }
140         });
141 
142         class StupidException extends RuntimeException {
143             private static final long serialVersionUID = 8829097977007580221L;
144         }
145 
146         try {
147             manager.withLock(new Runnable() {
148                 public void run() throws StupidException {
149                     called.set(true);
150                     throw new StupidException();
151                 }
152             });
153             fail("StupidException expected");
154         } catch (final StupidException ignore) {}
155 
156         assertTrue(called.get());
157         assertTrue(locked.get());
158         assertTrue(unlocked.get());
159     }
160 
161     @Test(expected = Exception.class)
162     public void reThrowsCallableException() throws Exception {
163         final ManagedLock manager = new ManagedLocks.ManagedLockImpl(new ReentrantLock());
164 
165         manager.withLock(new Callable<Void>() {
166             public Void call() throws Exception {
167                 throw new Exception();
168             }
169         });
170     }
171 }