View Javadoc
1   package org.eclipse.aether.named;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.junit.Assert;
23  import org.junit.Rule;
24  import org.junit.Test;
25  import org.junit.rules.TestName;
26  
27  import java.util.concurrent.CountDownLatch;
28  import java.util.concurrent.TimeUnit;
29  
30  import static org.hamcrest.MatcherAssert.assertThat;
31  import static org.hamcrest.Matchers.is;
32  import static org.hamcrest.Matchers.not;
33  import static org.hamcrest.Matchers.sameInstance;
34  
35  /**
36   * UT support for {@link NamedLockFactory}.
37   */
38  public abstract class NamedLockFactoryTestSupport {
39  
40      protected static NamedLockFactory namedLockFactory;
41  
42      @Rule
43      public TestName testName = new TestName();
44  
45      protected String lockName()
46      {
47          return testName.getMethodName();
48      }
49  
50      @Test
51      public void refCounting() {
52          final String name = lockName();
53          try (NamedLock one = namedLockFactory.getLock(name);
54               NamedLock two = namedLockFactory.getLock(name)) {
55              assertThat(one, sameInstance(two));
56              one.close();
57              two.close();
58  
59              try (NamedLock three = namedLockFactory.getLock(name)) {
60                  assertThat(three, not(sameInstance(two)));
61              }
62          }
63      }
64  
65      @Test(expected = IllegalStateException.class)
66      public void unlockWoLock() {
67          final String name = lockName();
68          try (NamedLock one = namedLockFactory.getLock(name)) {
69              one.unlock();
70          }
71      }
72  
73      @Test
74      public void wwBoxing() throws InterruptedException {
75          final String name = lockName();
76          try (NamedLock one = namedLockFactory.getLock(name)) {
77              assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true));
78              assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true));
79              one.unlock();
80              one.unlock();
81          }
82      }
83  
84      @Test
85      public void rrBoxing() throws InterruptedException {
86          final String name = lockName();
87          try (NamedLock one = namedLockFactory.getLock(name)) {
88              assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
89              assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
90              one.unlock();
91              one.unlock();
92          }
93      }
94  
95      @Test
96      public void wrBoxing() throws InterruptedException {
97          final String name = lockName();
98          try (NamedLock one = namedLockFactory.getLock(name)) {
99              assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true));
100             assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
101             one.unlock();
102             one.unlock();
103         }
104     }
105 
106     @Test
107     public void rwBoxing() throws InterruptedException {
108         final String name = lockName();
109         try (NamedLock one = namedLockFactory.getLock(name)) {
110             assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
111             assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(false));
112             one.unlock();
113         }
114     }
115 
116     @Test(timeout = 5000)
117     public void sharedAccess() throws InterruptedException {
118         final String name = lockName();
119         CountDownLatch winners = new CountDownLatch(2); // we expect 2 winners
120         CountDownLatch losers = new CountDownLatch(0); // we expect 0 losers
121         Thread t1 = new Thread(new Access(namedLockFactory, name, true, winners, losers));
122         Thread t2 = new Thread(new Access(namedLockFactory, name, true, winners, losers));
123         t1.start();
124         t2.start();
125         t1.join();
126         t2.join();
127         winners.await();
128         losers.await();
129     }
130 
131     @Test(timeout = 5000)
132     public void exclusiveAccess() throws InterruptedException {
133         final String name = lockName();
134         CountDownLatch winners = new CountDownLatch(1); // we expect 1 winner
135         CountDownLatch losers = new CountDownLatch(1); // we expect 1 loser
136         Thread t1 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
137         Thread t2 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
138         t1.start();
139         t2.start();
140         t1.join();
141         t2.join();
142         winners.await();
143         losers.await();
144     }
145 
146     @Test(timeout = 5000)
147     public void mixedAccess() throws InterruptedException {
148         final String name = lockName();
149         CountDownLatch winners = new CountDownLatch(1); // we expect 1 winner
150         CountDownLatch losers = new CountDownLatch(1); // we expect 1 loser
151         Thread t1 = new Thread(new Access(namedLockFactory, name, true, winners, losers));
152         Thread t2 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
153         t1.start();
154         t2.start();
155         t1.join();
156         t2.join();
157         winners.await();
158         losers.await();
159     }
160 
161     private static class Access implements Runnable {
162         final NamedLockFactory namedLockFactory;
163         final String name;
164         final boolean shared;
165         final CountDownLatch winner;
166         final CountDownLatch loser;
167 
168         public Access(NamedLockFactory namedLockFactory,
169                       String name,
170                       boolean shared,
171                       CountDownLatch winner,
172                       CountDownLatch loser) {
173             this.namedLockFactory = namedLockFactory;
174             this.name = name;
175             this.shared = shared;
176             this.winner = winner;
177             this.loser = loser;
178         }
179 
180         @Override
181         public void run() {
182             try (NamedLock lock = namedLockFactory.getLock(name)) {
183                 if (shared ? lock.lockShared(100L, TimeUnit.MILLISECONDS) : lock.lockExclusively(100L, TimeUnit.MILLISECONDS)) {
184                     try {
185                         winner.countDown();
186                         loser.await();
187                     } finally {
188                         lock.unlock();
189                     }
190                 } else {
191                     loser.countDown();
192                     winner.await();
193                 }
194             } catch (InterruptedException e) {
195                 Assert.fail(e.getMessage());
196             }
197         }
198     }
199 }